Fast Scrolling with RecyclerView

Shaishav Gandhi
AndroidPub
Published in
3 min readAug 26, 2017

--

Continuing with Support Library 26 features (if you missed the one with downloadable fonts), a much awaited feature was enabled : fast scrolling for RecyclerView.

Of all the great advantages RecyclerView has over ListView, one feature that I miss a lot is fast scrolling where you could drag a thumb drawable and scroll around the list. In ListView you could do the following :

listView = (ListView) findViewById(R.id.listView);
listView.setFastScrollEnabled(true);

But with RecyclerView, there is no easy way to have a thumb drawable like so :

Image credit : https://github.com/FutureMind/recycler-fast-scroll

So we would rely on libraries like this and this.

With Support Library 26, we can easily enable fast scrolling for RecyclerView. Let’s get to it!

Let’s make sure we’re getting the Support Library 26. The app build.gradle file will look something like :

dependencies {
....
compile 'com.android.support:design:26.0.1'
compile 'com.android.support:recyclerview-v7:26.0.1'
....
}

Since Support Library 26 has now been moved to Google’s maven repository, let’s include that in our project level build.gradle

buildscript {

repositories {
google()
}
....}

This is what our layout file for the activity looks like :

content_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.shaishavgandhi.fastscrolling.MainActivity"
tools:showIn="@layout/activity_main">


<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

I have setup a simple RecyclerView filled with mock data that shows US states and their state code. It looks something like :

Without fast scroll

Now let’s enable the fast scrolling. The updated xml file looks like :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.shaishavgandhi.fastscrolling.MainActivity"
tools:showIn="@layout/activity_main">


<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fastScrollEnabled="true"
app:fastScrollHorizontalThumbDrawable="
@drawable/thumb_drawable"
app:fastScrollHorizontalTrackDrawable="
@drawable/line_drawable"
app:fastScrollVerticalThumbDrawable="
@drawable/thumb_drawable"
app:fastScrollVerticalTrackDrawable="
@drawable/line_drawable">

</android.support.v7.widget.RecyclerView>

</android.support.constraint.ConstraintLayout>

Let’s go over each property one by one :

  • fastScrollEnabled : boolean value to enable the fast scrolling. Setting this as true will require that we provide the following four properties.
  • fastScrollHorizontalThumbDrawable : A StateListDrawable that will be used to draw the thumb which will be draggable across the horizontal axis.
  • fastScrollHorizontalTrackDrawable : A StateListDrawable that will be used to draw the line that will represent the scrollbar on horizontal axis.
  • fastScrollVerticalThumbDrawable : A StateListDrawable that will be used to draw the thumb which will be draggable on vertical axis.
  • fastScrollVerticalTrackDrawable : A StateListDrawable that will be used to draw the line that will represent the scrollbar on vertical axis.

Let’s look at the StateListDrawables. I’ve used native shapes so that you can easily reuse them.

line_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/line"/>

<item
android:drawable="@drawable/line"/>
</selector>

line.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:color="@android:color/darker_gray" />

<padding
android:top="10dp"
android:left="10dp"
android:right="10dp"
android:bottom="10dp"/>
</shape>

thumb_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="@drawable/thumb"/>

<item
android:drawable="@drawable/thumb"/>
</selector>

thumb.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<corners
android:topLeftRadius="44dp"
android:topRightRadius="44dp"
android:bottomLeftRadius="44dp" />

<padding
android:paddingLeft="22dp"
android:paddingRight="22dp" />

<solid android:color="@color/colorPrimaryDark" />

</shape>

This is what it looks like :

Awesome!

This is a basic example of enabling fast scrolling. It will be interesting to see how we can customize it to show letter initials like in the Contacts app.

If you want the full source code, it’s available on GitHub.

Until then, happy coding!

--

--