ViewPager2 내부에서 가로 스크롤 터치 처리

김토끼·2021년 10월 18일
0

android ViewPager2 내부에 가로로 스크롤 되는 RecyclerView가 있는 경우 바깥쪽 ViewPager에 userInputEnable 설정을 false로 변경해 줘야 안쪽 RecyclerView에서 스크롤 처리가 가능하다.

outerViewPager.isUserInputEnabled = false

대신 이렇게 하면 바깥쪽 ViewPager에서는 가로 swipe로는 페이지 변경이 불가능하다는 문제가 있다.
안쪽 RecyclerView가 화면 전체 영역을 차지하고 있다면 크게 문제가 되지 않겠지만 일부분의 영역만 차지하는 경우엔 안쪽, 바깥쪽 모두 swipe로 페이지 이동을 해야할 필요가 생긴다.
이럴떈 안쪽 RecyclerView에 RecyclerView.OnItemTouchListener와 GestureListener를 구현하면 된다.
ViewPager2의 경우 내부적으로 RecyclerView를 사용하므로 RecyclerView.OnItemTouchListener를 같이 사용할 수 있다.

class OnRecyclerItemTouchInterceptorListener(
    context: Context,
    private val rv: RecyclerView
): RecyclerView.OnItemTouchListener {
    private val gestureDetector = GestureDetector(context, GestureListener())

    override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
        gestureDetector.onTouchEvent(e)
        return false
    }

    override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) { /* nothing */ }

    override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) { /* nothing */ }

    private inner class GestureListener : SimpleOnGestureListener() {
        private val yMinRange = 10

        override fun onDown(e: MotionEvent): Boolean {
            rv.parent.requestDisallowInterceptTouchEvent(true)
            return super.onDown(e)
        }

        override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float): Boolean {
            if (abs(distanceX) < abs(distanceY)) {
                rv.parent.requestDisallowInterceptTouchEvent(false)
            } else if (abs(distanceX) > yMinRange) {
                rv.parent.requestDisallowInterceptTouchEvent(true)
            }
            return super.onScroll(e1, e2, distanceX, distanceY)
        }
    }
}

/**
 * for kotlin extension
 */
fun RecyclerView.onHorizontalScrollListener(context: Context) {
    this.addOnItemTouchListener(OnRecyclerItemTouchInterceptorListener(context, this))
}

usage

// setup RecyclerView
...
recyclerView.onHorizontalScrollListener(context)
profile
방구석 김토끼🐰

0개의 댓글