Update fast scroll behavior

Update the behavior of the fast scroller so that the scroll only begins when the pointer is in the indicator box itself, instead of the general view.
This commit is contained in:
OxygenCobalt 2021-03-24 08:47:14 -06:00
parent 54efad3fdf
commit 6d5ed6dd7b
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
6 changed files with 30 additions and 12 deletions

View file

@ -59,6 +59,7 @@ class FastScrollView @JvmOverloads constructor(
// --- STATE ---
private var hasPostedItemUpdate = false
private var wasValidTouch = false
private var lastPos = -1
init {
@ -147,6 +148,7 @@ class FastScrollView @JvmOverloads constructor(
@Suppress("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent): Boolean {
super.onTouchEvent(event)
performClick()
val success = handleTouch(event.action, event.x.roundToInt(), event.y.roundToInt())
@ -160,15 +162,25 @@ class FastScrollView @JvmOverloads constructor(
}
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
when (action) {
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
binding.scrollIndicatorText.setTextColor(inactiveColor)
wasValidTouch = false
lastPos = -1
return false
return false
}
// Since this view is unified between the thumb and the indicators, we have
// to check if the initial pointer position was in the indicators to prevent the
// scroll from being triggered outside its bounds.
MotionEvent.ACTION_DOWN -> {
wasValidTouch = binding.scrollIndicatorText.contains(touchX, touchY)
}
}
// Try to figure out which indicator the pointer has landed on
if (binding.scrollIndicatorText.isBeingPressed(touchX, touchY)) {
if (binding.scrollIndicatorText.containsY(touchY) && wasValidTouch) {
// 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
@ -214,10 +226,11 @@ class FastScrollView @JvmOverloads constructor(
}
}
/**
* Returns if the pointer is currently in the view
*/
private fun View.isBeingPressed(x: Int, y: Int): Boolean {
private fun View.contains(x: Int, y: Int): Boolean {
return x in (left until right) && containsY(y)
}
private fun View.containsY(y: Int): Boolean {
return y in (top until bottom)
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="@android:color/white" />
</shape>

View file

@ -12,7 +12,7 @@
android:id="@+id/accent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ui_circular_button"
android:background="@drawable/ui_circle_ripple"
android:padding="@dimen/margin_medium"
android:scaleType="fitCenter"
android:src="@drawable/ic_check"

View file

@ -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_circular_button"
android:background="@drawable/ui_circle"
android:elevation="@dimen/elevation_small"
android:backgroundTint="?attr/colorPrimary"
android:stateListAnimator="@animator/animator_thumb"

View file

@ -213,7 +213,7 @@
<style name="PlayPause">
<item name="android:layout_height">@dimen/size_play_pause</item>
<item name="android:layout_width">@dimen/size_play_pause</item>
<item name="android:background">@drawable/ui_circular_button</item>
<item name="android:background">@drawable/ui_circle_ripple</item>
<item name="android:backgroundTint">?attr/colorPrimary</item>
<item name="android:tint">?android:attr/windowBackground</item>
<item name="android:layout_marginStart">@dimen/margin_large</item>