36
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Android のリストをスワイプして削除する #あれどうやるの?

Last updated at Posted at 2018-06-15

用語

  • 「リスト」は RecyclerView の話です。
  • 「あれ」とはGmailアプリやInboxアプリで実装されている横にスワイプしてリストアイテムを削除(アーカイブ)するという動作のことです。

結論

ItemTouchHelper.SimpleCallback を使う

詳細

リストアイテムをスワイプすること自体割と簡単でした。

スワイプの実装

ItemTouchHelper.SimpleCallback は引数を取るのですが、2つ目の引数にスワイプする方向を設定してあげます。
今回は左右にスワイプしたいので ItemTouchHelper.RIGHTItemTouchHelper.LEFT を設定します。
第一引数は上下の移動を設定しますが、今回は使わないので 0 を設定します。

ItemTouchHelper.SimpleCallback(0, (ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT))

リストを削除

ItemTouchHelper.SimpleCallback には onSwiped という関数が用意されています。
スワイプした後にコールされるのでここでリストを削除します。

アイコンを表示する

ItemTouchHelper.SimpleCallback には onChildDraw という関数が用意されています。

override fun onChildDraw(
        c: Canvas?,
        recyclerView: RecyclerView?,
        viewHolder: RecyclerView.ViewHolder?,
        dX: Float,
        dY: Float,
        actionState: Int,
        isCurrentlyActive: Boolean

こちらもスワイプ時にコールされますが、 onSwiped と異なり、この関数は指を移動させるごとにコールされます。
また、パラメーターに Canvas が渡されるのですが、これはスワイプされたリストの裏側に描画するための Canvas になります。なのでこの Canvas に表示させたい絵を書きます。
Canvas の扱いは少し面倒ですが、ユーザーにスワイプをしたらどうなるのかを想起させることができるのでぜひやりましょう。

少し戻りますが、 ItemTouchHelperItemTouchHelper.RIGHTItemTouchHelper.LEFT を設定したのでリストアイテムは左右のスワイプができるようになっています。
しかしこの関数は左右どちらに移動した時もコールされるのでユーザーが左に動かしているのか、右に動かしているのかを判断する必要があります。
そこで dX というパラメータをみてどちらに移動しているかを判断できます。左方向に移動している時、 dX はマイナスの値を取るので以下のような条件式で判断が可能です。

val isLeftDirection = dX < 0

イメージですが、このように背景に色塗ります。

background.color = leftBackgroundColor
background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)

アイコンはこのように描画します。

// Calculate position of delete icon
val deleteIconTop = itemView.top + (itemHeight - deleteIconIntrinsicHeight) / 2
val deleteIconMargin = (itemHeight - deleteIconIntrinsicHeight) / 2
val deleteIconLeft = itemView.right - deleteIconMargin - deleteIconIntrinsicWidth
val deleteIconRight = itemView.right - deleteIconMargin
val deleteIconBottom = deleteIconTop + deleteIconIntrinsicHeight

// Draw the delete icon
deleteIcon.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom)
deleteIcon.draw(c)

以上です。サンプルコードを Github に作成しました。

リンク

http://yuki312.blogspot.com/2015/06/recyclerview-itemtouchhelper.html
https://medium.com/@kitek/recyclerview-swipe-to-delete-easier-than-you-thought-cff67ff5e5f6

36
47
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
36
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?