用語
- 「リスト」は RecyclerView の話です。
- 「あれ」とはGmailアプリやInboxアプリで実装されている横にスワイプしてリストアイテムを削除(アーカイブ)するという動作のことです。
結論
ItemTouchHelper.SimpleCallback
を使う
詳細
リストアイテムをスワイプすること自体割と簡単でした。
スワイプの実装
ItemTouchHelper.SimpleCallback
は引数を取るのですが、2つ目の引数にスワイプする方向を設定してあげます。
今回は左右にスワイプしたいので ItemTouchHelper.RIGHT
と ItemTouchHelper.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
の扱いは少し面倒ですが、ユーザーにスワイプをしたらどうなるのかを想起させることができるのでぜひやりましょう。
少し戻りますが、 ItemTouchHelper
に ItemTouchHelper.RIGHT
と ItemTouchHelper.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