在双向Recyclerview中处理水平滚动时禁用SwipeRefreshLayout

问题描述 投票:0回答:1

我有一个带有自定义LayoutManager的RecyclerView,它具有双向滚动逻辑。因此,我已经覆盖了它的方法:

override fun canScrollVertically(): Boolean = true
override fun canScrollHorizontally(): Boolean = true

然后我将RecyclerView放入自定义的SwipeRefreshLayout中,当用户水平滚动列表时防止“刷卡刷新”操作

class CustomSwipeToRefresh
@JvmOverloads
constructor(
        context: Context,
        attrs: AttributeSet? = null
) : SwipeRefreshLayout(context, attrs) {

    private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop
    private var startX = 0f
    private var forbidSwipe = false

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            ACTION_DOWN -> startX = event.x
            ACTION_MOVE -> {
                if (abs(event.x - startX) > touchSlop || forbidSwipe) {
                    forbidSwipe = true
                    return false
                }
            }
            ACTION_CANCEL, ACTION_UP -> {
                forbidSwipe = false
            }
        }
        return super.onInterceptTouchEvent(event)
    }

}

但是此解决方案不起作用。尝试过此解决方案(手动禁用),但也无法正常工作:

override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            ACTION_DOWN -> startX = event.x
            ACTION_MOVE -> {
                if (abs(event.x - startX) > touchSlop || forbidSwipe) {
                    forbidSwipe = true
                    isEnabled = false
                    return false
                }
            }
            ACTION_CANCEL, ACTION_UP -> {
                isEnabled = true
                forbidSwipe = false
            }
        }
        return super.onInterceptTouchEvent(event)
    }

无论如何,如果我写

refreshLayout.isEnabled = false

在我的Fragment中的onViewCreated中,它被禁用。

也尝试在RecyclerView.OnScrollListener中禁用SwipeRefreshLayout,但这没有帮助。我的代码或SwipeRefreshLayout有什么问题?

java android kotlin android-recyclerview swiperefreshlayout
1个回答
0
投票

好经过数天的谷歌搜索,我发现显示和移动微调器的所有魔力都位于NestedScrollingParent方法中。因此,我重写了onNestedScroll方法,如果forbidSwipe == true我只是忽略了超级方法:

class CustomSwipeToRefresh
@JvmOverloads
constructor(
        context: Context,
        attrs: AttributeSet? = null
) : SwipeRefreshLayout(context, attrs) {

    private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop
    private var startX = 0f
    private var startY = 0f
    private var forbidSwipe = false
    private var isStartScrolledByY = false

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            ACTION_DOWN -> {
                startX = event.x
                startY = event.y
            }
            ACTION_MOVE -> {
                val isScrolledByX = abs(event.x - startX) > touchSlop
                val isScrolledByY = abs(event.y - startY) > touchSlop
                if (!forbidSwipe && isScrolledByY) {
                    isStartScrolledByY = true
                }
                if ((isScrolledByX || forbidSwipe) && !isStartScrolledByY) {
                    forbidSwipe = true
                    return false
                }
            }
            ACTION_CANCEL, ACTION_UP -> {
                forbidSwipe = false
                isStartScrolledByY = false
            }
        }
        return super.onInterceptTouchEvent(event)
    }

    override fun onNestedScroll(target: View, dxConsumed: Int, dyConsumed: Int, dxUnconsumed: Int, dyUnconsumed: Int) {
        if (forbidSwipe) return
        super.onNestedScroll(target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.