
Horizontal, Vertical 방향이 혼재된 Nested RecyclerView를 구현하다 보면
세로 스크롤을 하는 도중 가로 스크롤로 넘어가는데 자연스럽지 않거나 그 반대 상황이 생긴다.
그럴때 기본 RecyclerView 대신 아래의 커스텀 RecyclerView를 사용하면 조금 더 자연스러워 진다.
간단하게 주석으로 무슨일을 하는지 적어두었다.
원 코드 출처는 여기이다.
public class OrientationAwareRecyclerView extends RecyclerView { private float lastX = 0.0f; private float lastY = 0.0f; private boolean scrolling = false; public OrientationAwareRecyclerView(@NonNull Context context) { this(context, null); } public OrientationAwareRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public OrientationAwareRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); addOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); scrolling = newState != RecyclerView.SCROLL_STATE_IDLE; } }); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { final LayoutManager lm = getLayoutManager(); if (lm == null) { return super.onInterceptTouchEvent(e); } boolean allowScroll = true; switch (e.getActionMasked()) { case MotionEvent.ACTION_DOWN: { lastX = e.getX(); lastY = e.getY(); // If we were scrolling, stop now by faking a touch release // 아마 Fling시에 손가락 터치로 멈추는거일듯... if (scrolling) { MotionEvent newEvent = MotionEvent.obtain(e); newEvent.setAction(MotionEvent.ACTION_UP); return super.onInterceptTouchEvent(newEvent); } break; } case MotionEvent.ACTION_MOVE: { // We're moving, so check if we're trying // to scroll vertically or horizontally so we don't intercept the wrong event. float currentX = e.getX(); float currentY = e.getY(); float dx = Math.abs(currentX - lastX); float dy = Math.abs(currentY - lastY); // 세로로 스크롤 할려고할경우 lm 이 세로 스크롤 가능한지 여부, 가로로 할경우 가로 스크롤 가능여부에 따름. // 만약 가로로 스크롤 하지 못하는 rv인데 가로로 스크롤 하려고 할 경우 Touch Event를 가로채는걸 막는다. allowScroll = dy > dx ? lm.canScrollVertically() : lm.canScrollHorizontally(); break; } } if (!allowScroll) { return false; } return super.onInterceptTouchEvent(e); } }
'프로그래밍 > Android' 카테고리의 다른 글
[안드로이드] WebView에서 세션 쿠키 활성화 하기 (소셜 로그인) (3) | 2021.03.14 |
---|---|
[안드로이드] Context 사용 범위 정리 (0) | 2021.03.12 |
[안드로이드] 에뮬레이터 감지 하는 법 (Detecting Emulator Device) (1) | 2021.03.08 |
[안드로이드] RecyclerView를 잘 사용하기 위한 팁들. (0) | 2021.02.05 |
[안드로이드] 예제로 알아보는 바인드된 서비스 (Bound Service) (0) | 2021.01.18 |