簡體   English   中英

在雙向 Recyclerview 中處理水平滾動時禁用 SwipeRefreshLayout

[英]Disable SwipeRefreshLayout when horizintal scroll handled in two-way Recyclerview

我有一個帶有自定義 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

在我的 onViewCreated 片段中,它被禁用了。

還嘗試在 RecyclerView.OnScrollListener 中禁用 SwipeRefreshLayout,但沒有幫助。 我的代碼或 SwipeRefreshLayout 有什么問題?

好的。 經過幾天的谷歌搜索,我發現所有顯示和移動微調器的魔法都位於 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)
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM