This is only a partial answer; I'm missing (at least) one piece of the puzzle, but hopefully someone else can figure it out.
Once you've added the necessary attributes to your <RecyclerView>
tag (as mentioned in the answer linked in OP's question), the sizing/positioning of the scrollbar thumb is controlled by three methods inside LinearLayoutManager
:
int computeVerticalScrollRange()
: The size of the scrollbar's track.
int computeVerticalScrollExtent()
: The size of the scrollbar's thumb.
int computeVerticalScrollOffset()
: The distance between the top of the scrollbar's track and the top of the scrollbar's thumb.
The units for these methods is arbitrary; you can use anything you'd like as long as all three methods share the same units. By default, LinearLayoutManager
will use one of two sets of units:
mSmoothScrollbarEnabled == true
: Use units based on the pixel sizes of the visible items in the RecyclerView
.
mSmoothScrollbarEnabled == false
: Use units based on the positions of the visible items in the RecyclerView
's adapter.
To control the size of the scrollbar's thumb yourself, you'll have to override these methods... but here's the piece I'm missing: In all of my experimentation, computeVerticalScrollExtent()
is never called by the system. That said, we can still show some progress here.
First, I've created a simple adapter that shows 500 CardView
s with the item's position inside. I've enabled fast scrolling with some really simple (but ugly) drawables. Here's what the scrollbar looks like with just a default LinearLayoutManager
implementation:
As you've found, with 500 (small) items, the scrollbar thumb is really small and quite hard to tap on. We can make the scrollbar dramatically larger by overriding computeVerticalScrollRange()
to just return a fixed constant... I picked 5000
essentially at random just to show the major change:
Of course, now the scrollbar doesn't work like you'd expect; scrolling the list by dragging on it as normal moves the thumb much more than it should, and fast scrolling the list by dragging on the thumb moves the list much less than it should.
On my device, with the randomly-chosen range of 5000
, overriding computeVerticalScrollOffset()
as follows makes the scrollbar thumb move perfectly as I scroll the list by dragging on it:
@Override
public int computeVerticalScrollRange(RecyclerView.State state) {
return 5000;
}
@Override
public int computeVerticalScrollOffset(RecyclerView.State state) {
return (int) (super.computeVerticalScrollOffset(state) / 23.5f);
}
However, this still doesn't fix the second issue: dragging on the thumb itself doesn't correctly scroll the list. As I mentioned above, it would seem like the appropriate thing to do here would be to override computeVerticalScrollExtent()
, but the system never invokes this method. I've even overridden it to simply throw an exception, and my app never crashes.
Hopefully this at least helps point people in the right direction for a full solution.
PS: The implementations of computeVerticalScrollRange()
and computeVerticalScrollOffset()
I've included in this answer are intentionally simple (read: bogus). "Real" implementations would be much more complex; the default LinearLayoutManager
implementations take into account device orientation, the first and last visible items in the list, the number of items off-screen in both directions, smooth scrolling, various layout flags, and so on.