From bc760cf7b17c64a47bab0785aa93917f32d3fb62 Mon Sep 17 00:00:00 2001 From: Jays2Kings Date: Sat, 24 Apr 2021 14:09:49 -0400 Subject: [PATCH] Fixes to fast scroller Using android back gesture no longer sometimes jump the screen Fix issue when sometimes dragging fastscroll tries to drag to the top on release --- .../tachiyomi/ui/base/MaterialFastScroll.kt | 28 +++++++++++++++++-- .../tachiyomi/ui/library/LibraryController.kt | 1 + .../util/view/ControllerExtensions.kt | 1 + 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/base/MaterialFastScroll.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/base/MaterialFastScroll.kt index 746623609e..5cd498eda7 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/base/MaterialFastScroll.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/base/MaterialFastScroll.kt @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.StaggeredGridLayoutManager import eu.davidea.fastscroller.FastScroller import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPxEnd import eu.kanade.tachiyomi.util.view.marginTop import kotlin.math.abs @@ -53,7 +54,7 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr } MotionEvent.ACTION_MOVE -> { val y = event.y - if (!canScroll && abs(y - startY) > 10) { + if (!canScroll && abs(y - startY) > 15.dpToPx) { canScroll = true handle.isSelected = true notifyScrollStateChange(true) @@ -69,6 +70,22 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { startY = 0f canScroll = false + val newEvent = MotionEvent.obtain(event) + recyclerView.post { + // Mimic touch event for recycler so it doesn't scroll back + val lastTag = recyclerView.tag + recyclerView.tag = noUpdate + newEvent.action = MotionEvent.ACTION_MOVE + recyclerView.dispatchTouchEvent(newEvent) + val newEvent2 = MotionEvent.obtain(newEvent) + newEvent2.action = MotionEvent.ACTION_CANCEL + recyclerView.dispatchTouchEvent(newEvent2) + newEvent2.recycle() + newEvent.recycle() + recyclerView.post { + recyclerView.tag = lastTag + } + } } } return super.onTouchEvent(event) @@ -91,7 +108,10 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr scrollOffset ) } else { - (layoutManager as LinearLayoutManager).scrollToPositionWithOffset(targetPos, scrollOffset) + (layoutManager as LinearLayoutManager).scrollToPositionWithOffset( + targetPos, + scrollOffset + ) } updateBubbleText(targetPos) } @@ -114,4 +134,8 @@ class MaterialFastScroll @JvmOverloads constructor(context: Context, attrs: Attr } } } + + companion object { + const val noUpdate = "don't update scroll" + } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 31c5b2c0f6..b56a109e9a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -219,6 +219,7 @@ class LibraryController( private var scrollListener = object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) + if (recyclerView.tag == MaterialFastScroll.noUpdate) return val recyclerCover = binding.recyclerCover if (!recyclerCover.isClickable && isAnimatingHopper != true) { if (preferences.autohideHopper().get()) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/util/view/ControllerExtensions.kt b/app/src/main/java/eu/kanade/tachiyomi/util/view/ControllerExtensions.kt index b37657c6a3..dd41a06f38 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/util/view/ControllerExtensions.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/util/view/ControllerExtensions.kt @@ -251,6 +251,7 @@ fun Controller.scrollViewWith( object : RecyclerView.OnScrollListener() { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { super.onScrolled(recyclerView, dx, dy) + if (recyclerView.tag == MaterialFastScroll.noUpdate) return if (router?.backstack?.lastOrNull() ?.controller() == this@scrollViewWith && statusBarHeight > -1 && activity != null && activityBinding!!.appBar.height > 0 &&