読者です 読者をやめる 読者になる 読者になる

アニマネ開発日誌

アニメアプリのアニマネの開発日誌です。

Androidにマテリアルデザインなスクロールバーを追加できるMaterialScrollBar

AndroidにはiOSのUITableViewにあるセクションインデックスがなくて、 常々不便だと思っていたのですが、MaterialScrollBarを使えば少し解消できそうです。

f:id:animane:20160426163446p:plain

セクションインデックスとは?

iOSに馴染みのない方に軽く説明しておくと、 リストビューの右側に設置される、リスト内の要素にアクセスするための索引です。

例えば電話帳で五十音順に並べたリストビューがあったとします。 ユーザーが「は」から始まる要素を探す時に、リストの数が多いとかなりスクロールする必要があります。

その時に直接「は」までスクロールできるようにするのが、セクションインデックスです。

参考までにiOS版のアニマネのスクリーンショットを掲載しておきます。

f:id:animane:20160426163810p:plain

利用条件

Githubのソースを見る限りでは、APIバージョン11以上をサポートしているようです。

また、現在対応しているのはRecyclerViewのみのため、 通常のListViewでは利用ができません。

導入

導入自体は簡単で、Githubに書いてあるとおり、Gradleに下記を追加します。

maven {
    jcenter()
}
dependencies {
    compile 'com.turingtechnologies.materialscrollbar:lib:9.+'
}

使い方

詳細なコードはGithubの説明が分かりやすいです。

1.スクロールビューの追加

レイアウトXMLでも、コードからでもどちらでも追加ができます。 レイアウトXMLを使うなら下記のような感じです。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                tools:context=".MainActivity">

    <android.support.v7.widget.RecyclerView
    android:id="@+id/list"
    android:name="com.examle.hoge.FooFragment"
    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:layoutManager="LinearLayoutManager"
    tools:context="com.example.hoge.FooFragment"
    tools:listitem="@layout/foo" />

    <com.turingtechnologies.materialscrollbar.DragScrollBar
        android:id="@+id/dragScrollBar"
        android:layout_width="wrap_content"
        app:recyclerView="@+id/list"
        app:lightOnTouch="true"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="false" />
    </RelativeLayout>

これだけでスクロールバーが動くようになります。

2.インジケーターの実装

スクロールした時に表示する文字を実装します。

RecyclerView.AdapterにINameableAdapterを実装する。

RecyclerViewのAdapterにINameableAdapterインターフェイスを定義し、 getCharacterForElementメソッドを実装します。

public class HogeRecyclerViewAdapter extends RecyclerView.Adapter<HogeRecyclerViewAdapter.ViewHolder> implements INameableAdapter {
    private List<Person> mValues;

    // 〜中略〜

    @Override
    public Character getCharacterForElement(int element) {
        Person person = mValues.get(element);
        String kana = pserson.getKana();
        Character c = new Character('#');
        if( kana != null && kana.length() > 0) {
            c = kana.charAt(0);
        }
        return c;
    }}

getCharacterForElementの引数にリスト要素のインデックスが入っているので、 あとは保持しているリストから表示したい文字を取り出すだけです。

DragScrollBarにAdapterを追加する。

Adapterの実装が終われば、あとはスクロールバーにセットしてあげます。 fragmentのonCreateViewなど、適切な場所でセットしてあげます。

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View scrollView = view.findViewById(R.id.dragScrollBar);
        if( scrollView instanceof DragScrollBar){
            DragScrollBar materialScrollBar = (DragScrollBar) scrollView;
            materialScrollBar.addIndicator(new AlphabetIndicator(this.getContext()),false);
        }
    }

ここまで実装すれば、インデックス文字付きのスクロールバーになります。

長いリストだとスクロールバーがあるかないかでユーザービリティが全く変わってくるので、ぜひともお試しください。

アニマネのAndroid版でも次のアップデートで組み込む予定です。