From 688f9d3a52b781b0acbcab7b004d8226aff3eaca Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Tue, 23 Mar 2021 17:06:06 -0600 Subject: [PATCH] Fix fast-scroll bugs Fix some behavior issues with the new fast scroll view. --- .../org/oxycblt/auxio/songs/FastScrollView.kt | 23 +++++++++++++------ app/src/main/res/layout/view_fast_scroll.xml | 4 ++-- app/src/main/res/values/dimens.xml | 2 +- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt b/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt index 9cde7fc86..64c96b447 100644 --- a/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt +++ b/app/src/main/java/org/oxycblt/auxio/songs/FastScrollView.kt @@ -6,6 +6,7 @@ import android.util.AttributeSet import android.util.TypedValue import android.view.HapticFeedbackConstants import android.view.MotionEvent +import android.view.View import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.view.isVisible import androidx.dynamicanimation.animation.DynamicAnimation @@ -13,7 +14,6 @@ import androidx.dynamicanimation.animation.SpringAnimation import androidx.dynamicanimation.animation.SpringForce import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.ViewFastScrollBinding import org.oxycblt.auxio.logD import org.oxycblt.auxio.ui.Accent @@ -27,7 +27,7 @@ import kotlin.math.roundToInt /** * A view that allows for quick scrolling through a [RecyclerView] with many items. Unlike other - * fast-scrollers, this one displays indicators instead of simply a scroll bar. + * fast-scrollers, this one displays indicators and a thumb instead of simply a scroll bar. * This code is fundamentally an adaptation of Reddit's IndicatorFastScroll, albeit specialized * towards Auxio. The original library is here: https://github.com/reddit/IndicatorFastScroll/ * @author OxygenCobalt @@ -73,7 +73,8 @@ class FastScrollView @JvmOverloads constructor( } /** - * Set up this view with a [RecyclerView] and a corresponding [FastScrollThumb]. + * Set up this view with a [RecyclerView]. [getItem] is called when the first character + * of a piece of data is needed. */ fun setup(recycler: RecyclerView, getItem: (Int) -> Char) { check(mRecycler == null) { "Only set up this view once." } @@ -95,6 +96,7 @@ class FastScrollView @JvmOverloads constructor( if (recycler.isAttachedToWindow && recycler.adapter != null) { updateIndicators() + binding.scrollIndicatorText.requestLayout() } // Hide this view if there is nothing to scroll @@ -147,17 +149,17 @@ class FastScrollView @JvmOverloads constructor( override fun onTouchEvent(event: MotionEvent): Boolean { performClick() - val success = handleTouch(event.action, event.y.roundToInt()) + val success = handleTouch(event.action, event.x.roundToInt(), event.y.roundToInt()) // Depending on the results, update the visibility of the thumb and the pressed state of // this view. - isPressed = success binding.scrollThumb.isActivated = success + binding.scrollIndicatorText.isPressed = success return success } - private fun handleTouch(action: Int, touchY: Int): Boolean { + private fun handleTouch(action: Int, touchX: Int, touchY: Int): Boolean { if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { binding.scrollIndicatorText.setTextColor(inactiveColor) lastPos = -1 @@ -166,7 +168,7 @@ class FastScrollView @JvmOverloads constructor( } // Try to figure out which indicator the pointer has landed on - if (touchY in (binding.scrollIndicatorText.top until binding.scrollIndicatorText.bottom)) { + if (binding.scrollIndicatorText.isBeingPressed(touchX, touchY)) { // Get the touch position in regards to the TextView and the rough text height val indicatorTouchY = touchY - binding.scrollIndicatorText.top val textHeight = binding.scrollIndicatorText.height / indicators.size @@ -211,4 +213,11 @@ class FastScrollView @JvmOverloads constructor( ) } } + + /** + * Returns if the pointer is currently in the view + */ + private fun View.isBeingPressed(x: Int, y: Int): Boolean { + return (x in (left until right) && y in (top until bottom)) || isPressed + } } diff --git a/app/src/main/res/layout/view_fast_scroll.xml b/app/src/main/res/layout/view_fast_scroll.xml index b78dc683c..30f2095ce 100644 --- a/app/src/main/res/layout/view_fast_scroll.xml +++ b/app/src/main/res/layout/view_fast_scroll.xml @@ -12,7 +12,7 @@ android:id="@+id/scroll_thumb" android:layout_width="@dimen/size_scroll_thumb" android:layout_height="@dimen/size_scroll_thumb" - android:background="@drawable/ui_circle" + android:background="@drawable/ui_circular_button" android:elevation="@dimen/elevation_small" android:backgroundTint="?attr/colorPrimary" android:stateListAnimator="@animator/animator_thumb" @@ -32,7 +32,7 @@ 32dp - 50dp 1dp + 18dp 64dp