Отключите SwipeRefreshLayout, когда горизонтальная прокрутка обрабатывается в двустороннем представлении Recyclerview - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть RecyclerView с пользовательским LayoutManager, который имеет двустороннюю логику прокрутки c. Итак, я переопределил его методы:

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

Затем я поместил RecyclerView в пользовательский SwipeRefreshLayout, , чтобы предотвратить действие «swipe to refre sh», когда пользователь прокручивает мой список по горизонтали :

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 во Fragment, оно станет отключенным.

Также попытался отключить SwipeRefreshLayout в RecyclerView.OnScrollListener, но это не помогло. Что не так в моем коде или SwipeRefreshLayout?

1 Ответ

0 голосов
/ 12 февраля 2020

Хорошо. После нескольких дней поиска в Google я обнаружил, что все маги c показа и перемещения блесны расположены в методах NestedScrollingParent. Итак, я переопределил метод onNestedScroll, и если forbidSwipe == true, я просто игнорирую метод super:

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

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...