I have a RecyclerView with custom LayoutManager, that has two-way scrolling logic. So, I have overrided it's methods:
override fun canScrollVertically(): Boolean = true
override fun canScrollHorizontally(): Boolean = true
Then i put RecyclerView in custom SwipeRefreshLayout, to prevent "swipe to refresh" action when user scrolls my list horizontally :
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)
}
}
But this solution doesn't work. Tryed this solution (disabling manualy), but it doesn't work too:
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)
}
Anyway, if I write
refreshLayout.isEnabled = false
in my onViewCreated in Fragment, it became disabled.
Also tryed to disable SwipeRefreshLayout in RecyclerView.OnScrollListener, but it didn't help. What is wrong in my code, or SwipeRefreshLayout?
Ok. After several days of googling I found that all magic of showing and moving spinner located in NestedScrollingParent methods. So, I overrided onNestedScroll method and if forbidSwipe == true
I just ignore super method:
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)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.