Я нашел несколько вопросов о StackOverflow, которые были несколько похожи на мои, но ни один из них не подходил полностью. Вот мое решение.
Пользовательский SwipeRefreshLayout, который может переключать его InterceptTouchEvent
:
class ToggleableSwipeRefreshLayout : SwipeRefreshLayout {
private var isDisabled = false
private var touchSlop = ViewConfiguration.get(context).scaledTouchSlop
private var prevX = 0f
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
fun setDisabled(isDisabled: Boolean) {
this.isDisabled = isDisabled
parent.requestDisallowInterceptTouchEvent(isDisabled)
}
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
val event = MotionEvent.obtain(ev)
prevX = event.x
event.recycle()
}
MotionEvent.ACTION_MOVE -> {
if (isDisabled) { return false }
val eventX = ev.x
val xDiff = Math.abs(eventX - prevX)
if (xDiff > touchSlop) {
return false
}
}
}
return super.onInterceptTouchEvent(ev)
}
}
А во фрагменте / действии, в котором это используется, добавьте OnPageChangeListener
в ViewPager для мониторинга состояния прокрутки и соответственно включите / отключите InterceptTouchEvent
в SwipeRefreshLayout:
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
when (state) {
ViewPager.SCROLL_STATE_DRAGGING -> swipeLayout.setDisabled(true)
ViewPager.SCROLL_STATE_IDLE -> swipeLayout.setDisabled(false)
}
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { }
override fun onPageSelected(position: Int) { }
})
Теперь все отлично работает!