Androidアプリ開発 RecyclerViewで一覧画面のスワイプを作成する

2016年04月09日(編集2016年04月09日)
このエントリーをはてなブックマークに追加

Androidアプリで一覧データのUI(ユーザーインターフェース)を作成する場合は、ListViewかRecyclerViewを使います。RecyclerViewで作成した一覧画面では、スワイプを実装することが可能です。

この記事は、RecyclerViewでスワイプの実装方法を記載した記事です。
環境はAndroid 6.0 (API level 23) です。

環境

  • android sdk 23
  • Build Tools, Revision 23.0.2
  • support recyclerview 23.2.0

難易度

中級者向け

サンプルコード

https://github.com/java-lang-programming/Android-RecyclerView-Demo

RecyclerViewとは

RecyclerViewクラスは、Androidアプリで一覧画面のUIを作成する時に利用します。

RecyclerViewで作成した一覧画面

スワイプ

スワイプは、画面で指を滑らせる操作のことです。

Google Playのスワイプ

RecyclerViewのスワイプ機能は、一覧表示の項目を動作させることが可能です。

RecyclerViewのスワイプ

スワイプの実装

RecyclerViewでスワイプを実装するには、一覧表示の実装ができることが前提です。
一覧表示の実装方法を理解してないなら、「RecyclerViewで一覧画面を作成する」の記事を読んで、一覧表示の実装をできるようにしてください。

使用クラス

ItemTouchHelperクラスを利用します。

ItemTouchHelperクラスは、RecyclerViewにスワイプやドラッグ&ドロップ機能を追加できます。

スワイプ実装

一覧表示のRecycleViewに、スワイプ機能を追加します。

スワイプ機能はItemTouchHelperクラスを利用します。コード内で以下のようにItemTouchHelperを生成します。

{project_folder}/app/java/package/ui/RecyclerViewSwipeFragment.java
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_list, container, false);

        // init swipe to dismiss logic
        ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
            }

            @Override
            public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                                        RecyclerView.ViewHolder viewHolder, float dX, float dY,
                                        int actionState, boolean isCurrentlyActive) {
            }
        });

        // Set the adapter
        if (view instanceof RecyclerView) {
            Context context = view.getContext();
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
            recyclerView.setAdapter(new MyItemRecyclerViewAdapter(DummyContent.ITEMS));
            swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
        }
        return view;
    }
        

ItemTouchHelperは、RecyclerView.ItemDecorationのサブクラスで、OnChildAttachStateChangeListenerインターフェースを実装しています。

public class ItemTouchHelper extends RecyclerView.ItemDecoration
  implements RecyclerView.OnChildAttachStateChangeListener {
}
        
ItemTouchHelper UML

ItemTouchHelperクラスのコンストラクタにSimpleCallbackクラスを設定します。
ItemTouchHelper.SimpleCallbackクラスはabstractクラスです。匿名クラスで具体的な実装をしています。

new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
    ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        // something
    });
        

生成したItemTouchHelperクラスのオブジェクトswipeToDismissTouchHelperでattachToRecyclerViewメソッドを呼び出し、RecyclerViewに機能を追加します。

swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
        

ビルドして実行

ビルドしてアプリを実行します。

アプリでスワイプを実施

スワイプ処理が可能になりました。

スワイプ後の処理実装

さらに、スワイプ後の処理を実装してみます。

スワイプ後の処理は、onSwipedメソッドを使用します。

{project_folder}/app/java/package/ui/RecyclerViewSwipeFragment.java
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_list, container, false);

        // init swipe to dismiss logic
        ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                mList.remove(viewHolder.getAdapterPosition());
                adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
            }

            @Override
            public void onChildDrawOver(Canvas c, RecyclerView recyclerView,
                                        RecyclerView.ViewHolder viewHolder, float dX, float dY,
                                        int actionState, boolean isCurrentlyActive) {
            }
        });

        // Set the adapter
        if (view instanceof RecyclerView) {
            Context context = view.getContext();
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setLayoutManager(new LinearLayoutManager(context));
            recyclerView.setAdapter(new MyItemRecyclerViewAdapter(DummyContent.ITEMS));
            swipeToDismissTouchHelper.attachToRecyclerView(recyclerView);
        }
        return view;
    }
        

ItemTouchHelper.CallbackクラスのonSwipedメソッドをオーバーライドします。
リストデータを削除し、アダプターでRecyclerVieweに削除を通知します。

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
    mList.remove(viewHolder.getAdapterPosition());
    adapter.notifyItemRemoved(viewHolder.getAdapterPosition());
}
        

ビルドして実行

ビルドしてアプリを実行します。

アプリでスワイプを実施

スワイプ処理後にデータが削除されるようになりました。

まとめ

ItemTouchHelperを利用すると、RecyclerViewで簡単にスワイプ処理を実装することができます。

ユーザーインターフェース的に使いどころの難しい機能ですが、GmailやInboxを参考に機能を実装してみてはいかがでしょうか。

是非挑戦してください。

TIPS

スワイプのアニーメーション中に背景が変化するGmail風のユーザーインターフェースは、ItemTouchHelperでは実現できません。

スクロールの処理中のviewを変える必要があるので、スクロール処理を変更してください。

関連記事

タグ検索で調べてみよう

Android6.0 UI