Skip to content

Commit e76568f

Browse files
Enhancement (Card Browser): Tap and drag scrollbar
1 parent 3f0b776 commit e76568f

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

AnkiDroid/src/main/java/com/ichi2/anki/ui/RecyclerFastScroller.kt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,47 @@ class RecyclerFastScroller
372372
}
373373
}
374374

375+
override fun onTouchEvent(event: MotionEvent): Boolean {
376+
return when (event.actionMasked) {
377+
MotionEvent.ACTION_DOWN, MotionEvent.ACTION_MOVE -> {
378+
// Retrieve the adapter to determine item count.
379+
val adapter = recyclerView?.adapter ?: return false
380+
381+
// Force the handle to be selected since the user is touching the track (the parent container) and not the handle itself.
382+
handle.isSelected = true
383+
384+
// The valid scroll area is (height-handle.height), since the position of the handle is defined by it's top edge, we subtract it.
385+
val scrollableHeight = height - handle.height
386+
387+
// Subtract half the handle's height and divide by 2 so the handle centers below the user's finger instead of hanging above or below.
388+
// Divide by the scrollableHeight to make sure that the handle doesn't go off the screen and we use coerceAtLeast to prevent divide by 0 errors
389+
val scrollProportion =
390+
((event.y - handle.height / 2) / scrollableHeight.coerceAtLeast(1))
391+
.coerceIn(0f, 1f)
392+
393+
// Calculates the item index we want to go to by multiplying our ScrollProportion to the item count
394+
// e.g. if we are going to 50% then 0.5*itemcount gives us the index we need.
395+
// toInt prevents decimal values, and coerceIn here makes it so when we scroll all the way to the end, we don't get an out of bounds error.
396+
val targetPosition =
397+
(scrollProportion * adapter.itemCount)
398+
.toInt()
399+
.coerceIn(0, adapter.itemCount - 1)
400+
401+
try {
402+
recyclerView?.scrollToPosition(targetPosition)
403+
} catch (e: Exception) {
404+
Timber.w(e, "scrollToPosition")
405+
}
406+
true
407+
}
408+
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
409+
handle.isSelected = false
410+
false
411+
}
412+
else -> super.onTouchEvent(event)
413+
}
414+
}
415+
375416
override fun onLayout(
376417
changed: Boolean,
377418
left: Int,

0 commit comments

Comments
 (0)