【问题标题】:Android Nested RecyclerView Change Angle Of ScrollAndroid Nested RecyclerView 改变滚动角度
【发布时间】:2018-11-27 08:59:32
【问题描述】:

我在垂直 RecyclerView 中有水平 recyclerViews。 要水平滚动,我应该从 45 度滑动到 -45 度。从 90 度垂直滚动到 45 度。有没有可能覆盖这个?

例如,垂直滚动仅适用于从 105 到 75 度的滑动。否则,水平滚动。

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    你需要像这样创建MainVerticalRecyclerView

    open class MainVerticalRecyclerView : RecyclerView {
    
        private var scrollPointerId = -1
        private var pointTouchX = 0
        private var pointTouchY = 0
        private var touchSlopType = 0
    
        constructor(context: Context) : this(context, null)
    
        constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
            val vc = ViewConfiguration.get(context)
            touchSlopType = vc.scaledTouchSlop
        }
    
        override fun setScrollingTouchSlop(slopConstant: Int) {
            super.setScrollingTouchSlop(slopConstant)
    
            val vc = ViewConfiguration.get(context)
            when (slopConstant) {
                TOUCH_SLOP_DEFAULT -> touchSlopType = vc.scaledTouchSlop
                TOUCH_SLOP_PAGING -> touchSlopType = vc.scaledPagingTouchSlop
            }
        }
    
        override fun onInterceptTouchEvent(e: MotionEvent?): Boolean {
            if (e == null) {
                return false
            }
    
            val action = e.actionMasked
            val actionIndex = e.actionIndex
    
            when (action) {
                MotionEvent.ACTION_DOWN -> {
                    scrollPointerId = e.getPointerId(0)
                    pointTouchX = Math.round(e.x + 0.5f)
                    pointTouchY = Math.round(e.y + 0.5f)
                    return super.onInterceptTouchEvent(e)
                }
    
                MotionEvent.ACTION_POINTER_DOWN -> {
                    scrollPointerId = e.getPointerId(actionIndex)
                    pointTouchX = Math.round(e.getX(actionIndex) + 0.5f)
                    pointTouchY = Math.round(e.getY(actionIndex) + 0.5f)
                    return super.onInterceptTouchEvent(e)
                }
    
                MotionEvent.ACTION_MOVE -> {
                    val index = e.findPointerIndex(scrollPointerId)
                    if (index < 0) {
                        return false
                    }
    
                    val x = Math.round(e.getX(index) + 0.5f)
                    val y = Math.round(e.getY(index) + 0.5f)
                    if (scrollState != SCROLL_STATE_DRAGGING) {
                        val dx = x - pointTouchX
                        val dy = y - pointTouchY
                        var startScroll = false
                        if (layoutManager?.canScrollHorizontally() == true && Math.abs(dx) > touchSlopType && (layoutManager?.canScrollVertically() == true || Math.abs(dx) > Math.abs(dy))) {
                            startScroll = true
                        }
                        if (layoutManager?.canScrollVertically() == true && Math.abs(dy) > touchSlopType && (layoutManager?.canScrollHorizontally() == true || Math.abs(dy) > Math.abs(dx))) {
                            startScroll = true
                        }
                        return startScroll && super.onInterceptTouchEvent(e)
                    }
                    return super.onInterceptTouchEvent(e)
                }
                else -> {
                    return super.onInterceptTouchEvent(e)
                }
            }
        }
    }
    

    并为其他嵌套在主RecyclerView 内的RecyclerView 创建ChildHorizontalRecyclerView,如下所示:

    class ChildHorizontalRecyclerView : MainVerticalRecyclerView {
        constructor(context: Context) : this(context, null)
    
        constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    
        constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    
        override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
    }
    

    如果您想在触摸PlayStore 时像PlayStore 一样滚动,则需要写:

            recyclerView.addOnItemTouchListener(object : RecyclerView.OnItemTouchListener {
                override fun onTouchEvent(rv: RecyclerView, e: MotionEvent) {}
                override fun onInterceptTouchEvent(rv: RecyclerView, e: MotionEvent): Boolean {
                    if (e.action == MotionEvent.ACTION_DOWN && rv.scrollState == RecyclerView.SCROLL_STATE_SETTLING) {
                        rv.stopScroll()
                    }
                    return false
                }
    
                override fun onRequestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
            })
    

    【讨论】:

      猜你喜欢
      • 2016-11-24
      • 1970-01-01
      • 2018-11-06
      • 1970-01-01
      • 1970-01-01
      • 2015-01-25
      • 2015-01-27
      • 1970-01-01
      • 2021-06-02
      相关资源
      最近更新 更多