Android嵌套RecyclerView改变滚动角度

标签 android android-recyclerview

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

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

最佳答案

您需要像这样创建 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 创建 ChildHorizo​​ntalRecyclerView,如下所示:

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) {}
}

如果你想在触摸 Horizo​​ntalChildRecyclerView 时像在 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) {}
        })

关于Android嵌套RecyclerView改变滚动角度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53495948/

相关文章:

android - 移动设备上侧边栏定位的 CSS 问题

kotlin - Lateinit 属性数据尚未初始化

android - 我可以在另一个类/Activity 中使用 ItemCount() 方法值吗?

android - ADT 在 Strings.xml 中显示错误

android - 在加载 webview 之前显示 Activity 圈 - Android

具有 Intent 操作的 Android Activity 。SEND 获取无法打开的 uri?

Android:防止软键盘在聊天窗口中关闭

java - 为什么android SDK-24需要JDK 1.8或更高版本才能编译? SDK-24 与 JDK 有何区别?

java - 在这个 RecyclerView 点击监听器中这个接口(interface)是干什么的?

android - 来自 Firebase 的数据未显示在 RecyclerView 上