LoginSignup
12
6

More than 5 years have passed since last update.

RecyclerViewでFastScroll

Last updated at Posted at 2018-01-20

ListViewやGridView(つまりAbsListView)なら、レイアウトXMLで以下のように書くだけで実現できた。

<ListView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fastScrollEnabled="true" />

RecyclerViewではこれができない、という状況が長く続いていた。
ライブラリを導入しようにも、決定版になるようなものは出ていなかった(個人の感想)。

……と思っていたのだが、久しぶりに調べてみたところ、Support Library 26でAPIが追加されたとのこと。
https://developer.android.com/topic/libraries/support-library/revisions.html#26-0-0

New fastScrollEnabled boolean flag for RecyclerView. If enabled, fastScrollHorizontalThumbDrawable, fastScrollHorizontalTrackDrawable, fastScrollVerticalThumbDrawable, and fastScrollVerticalTrackDrawable must be set.

動作イメージ

サンプルコードの実装抜粋

https://gist.github.com/75py/3b510a511d3d3231bc409e5517207818

設定方法

Layout XML

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:fastScrollEnabled="true"
    app:fastScrollHorizontalThumbDrawable="@drawable/fast_scroll_thumb"
    app:fastScrollHorizontalTrackDrawable="@drawable/fast_scroll_track"
    app:fastScrollVerticalThumbDrawable="@drawable/fast_scroll_thumb"
    app:fastScrollVerticalTrackDrawable="@drawable/fast_scroll_track" />
  • android:fastScrollAlwaysVisibleのような細かい指定はできないので、AbsListViewと完全に同等のことができる、というわけではなさそう。
  • 縦横どちらかにしかスクロールしない場合でも、Vertical/Horizontal両方の指定が必要(いずれかが欠けていると例外がスローされる)

java.lang.IllegalArgumentException: Trying to set fast scroller without both required drawables.

Drawable XML

基本的には、これだけで良い。

fast_scroll_thumb.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <solid android:color="#f00" />
        </shape>
    </item>
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#00f" />
        </shape>
    </item>
</selector>
fast_scroll_track.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#0f0" />
</shape>

個人的には、trackの方は透明でいいと思う。

fast_scroll_track_transparent.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/transparent" />
</shape>

Drawable XML(改善案 API23以降)

↑だと触れる範囲が非常に小さいので、正直言って使いづらい。

ソースを覗く限り、そのうち margin みたいな値が指定できるようになりそうだが、とりあえず Drawable を工夫してあげると、触れる範囲を広げることができる。

以下の例では、ツマミ8dpの左側40dpも触れるようにしてみた。
【2018/1/24追記】以下の例だと、API22以下でツマミの幅が48dpになってしまう。(自分のアプリはminSdkVersion=24にしているから気付かなかった)

fast_scroll_thumb2.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <layer-list>
            <item android:gravity="end">
                <shape android:shape="rectangle">
                    <solid android:color="#f00" />
                    <size android:width="8dp" />
                </shape>
            </item>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/transparent" />
                    <size android:width="48dp" />
                </shape>
            </item>
        </layer-list>
    </item>
    <item>
        <layer-list>
            <item android:gravity="end">
                <shape android:shape="rectangle">
                    <solid android:color="#00f" />
                    <size android:width="8dp" />
                </shape>
            </item>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/transparent" />
                    <size android:width="48dp" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

Drawable XML(改善案その2)

 前述の例だと、API22以下でツマミの幅が48dpになってしまう。
(API22-23の間にXMLの解釈方法が変わっているようだが、どういう理屈かまでは追っていない)
変更点は「gravity → left」のみ。。

fast_scroll_thumb3.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <layer-list>
            <item android:left="40dp">
                <shape android:shape="rectangle">
                    <solid android:color="#f00" />
                    <size android:width="8dp" />
                </shape>
            </item>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/transparent" />
                    <size android:width="48dp" />
                </shape>
            </item>
        </layer-list>
    </item>
    <item>
        <layer-list>
            <item android:left="40dp">
                <shape android:shape="rectangle">
                    <solid android:color="#00f" />
                    <size android:width="8dp" />
                </shape>
            </item>
            <item>
                <shape android:shape="rectangle">
                    <solid android:color="@android:color/transparent" />
                    <size android:width="48dp" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>
12
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6