【正社員】還元率83%【フリーランス】マージン一律5万円で案件をご紹介させていただきます。 詳細はこちら

【Android】<Kotlin>ItemTouchHelperを使って、リストの項目をスワイプして削除する方法を徹底解説!

【Android】<Kotlin>ItemTouchHelperを使って、リストの項目をスワイプして削除する方法を徹底解説!
すだ

みなさまこんにちは〜!
メモリアインクのすだです。

本日は、
KotlinのItemTouchHelperを使って
リストの項目をスワイプして削除する方法を、
実際のコードを利用して徹底解説していきます!

この記事を読んでわかること…
・ItemTouchHelperとは?
・ItemTouchHelperでスワイプ削除を実装する方法
・ドラッグ中のアイテムの背景色を変更する方法

目次

環境

  • Kotlin (ver 1.9.0)
  • Android Studio (Giraffe | 2022.3.1 Patch 3)

スワイプ削除の利用シーン

モバイルアプリのスワイプ削除機能は、以下のようなシーンで利用されます。

  • メールアプリ:
    • メールをスワイプで削除またはアーカイブ。
  • タスクリストアプリ:
    • 完了したタスクを簡単に削除。
  • メモアプリ:
    • 不要なメモをスワイプで削除。

ドラッグ&ドロップでリストのアイテムを並び替える機能に加えて、
スワイプしてリストのアイテムを削除できる機能を備えているアプリはたくさんあります。

ItemTouchHelperとは?

ItemTouchHelper は、RecyclerViewでドラッグやスワイプの操作を簡単に実現するためのユーティリティクラスです。
このクラスを利用することで、アイテムの並び替えや削除をスムーズに実装できます。

ItemTouchHelperは、以下の3つの主要なメソッドを持つCallbackクラスを利用して、操作をカスタマイズします。

  1. getMovementFlags:
    • ドラッグやスワイプの方向を指定します。
  2. onMove:
    • アイテムがドラッグされたときの動作を定義します。
  3. onSwiped:
    • アイテムがスワイプされたときの動作を定義します。

ドラッグ&ドロップでアイテム順を並び替える機能については、以下の記事でご紹介しています。
ぜひあわせてご覧ください!

ItemTouchHelperとは?

ItemTouchHelper は、RecyclerViewでドラッグやスワイプの操作を簡単に実現するためのユーティリティクラスです。
このクラスを利用することで、アイテムの並び替えや削除をスムーズに実装できます。

ItemTouchHelperは、以下の3つの主要なメソッドを持つCallbackクラスを利用して、操作をカスタマイズします。

  1. getMovementFlags:
    • ドラッグやスワイプの方向を指定します。
  2. onMove:
    • アイテムがドラッグされたときの動作を定義します。
  3. onSwiped:
    • アイテムがスワイプされたときの動作を定義します。

ItemTouchHelperを使ってスワイプ削除を実装する方法

それでは早速実装していきましょう!

ここでは、RecyclerViewでリストを作成して、
アイテムをスワイプして削除が可能な機能の実装を解説します。

1. レイアウトファイル

まずは、RecyclerViewを配置するためのレイアウトファイルを作成します。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2. MainActivity.kt

次に、RecyclerViewを初期化し データを設定します。

class MainActivity : AppCompatActivity() {

    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: ItemAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView = findViewById(R.id.recyclerView)
        val items = mutableListOf("Item 1", "Item 2", "Item 3", "Item 4")

        adapter = ItemAdapter(items)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter

        val itemTouchHelper = ItemTouchHelper(SwipeToDeleteCallback(adapter))
        itemTouchHelper.attachToRecyclerView(recyclerView)
    }
}

17〜18行目:

  • ItemTouchHelperの作成
    • SwipeToDeleteCallback クラス(スワイプ削除の挙動を定義)を使って、ItemTouchHelper を初期化します。
  • RecyclerViewにアタッチ
    • itemTouchHelper.attachToRecyclerView(recyclerView) で、RecyclerViewにスワイプ削除機能を関連付けます。

3. ItemMoveCallback.kt

そして、ItemTouchHelper.Callbackを拡張して ドラッグ操作を実装します。

class SwipeToDeleteCallback(private val adapter: ItemAdapter) : ItemTouchHelper.Callback() {

    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        val swipeFlags = ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
        return makeMovementFlags(0, swipeFlags)
    }

    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        // ドラッグ操作は使用しないためfalseを返す
        return false
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        val position = viewHolder.adapterPosition
        adapter.removeItem(position)
    }
}

このコードは、RecyclerViewのアイテムをスワイプで削除する挙動を定義するクラスです。

3行目:

  • getMovementFlags
    • スワイプの方向を指定します。
    • ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT で左右方向のドラッグを許可しています。

8行目:

  • onMove
    • ドラッグ操作は無効化しているため、false を返します。

17行目:

  • onSwiped
    • アイテムがスワイプされたときに呼び出され、adapter.removeItem(position) でデータリストから該当アイテムを削除します。

4. ItemAdapter.kt

最後に、RecyclerViewのアダプターを作成します。

class ItemAdapter(private val items: MutableList<String>) : RecyclerView.Adapter<ItemAdapter.ViewHolder>() {

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        val textView: TextView = itemView.findViewById(R.id.itemText)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.item_layout, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = items[position]
    }

    override fun getItemCount(): Int = items.size

    fun removeItem(position: Int) {
        items.removeAt(position)
        notifyItemRemoved(position)
    }
}

18行目:

このコード(onItemMove)は、RecyclerViewのアイテムをスワイプで削除する場合に、データの順序を入れ替えて画面に反映する処理です。

  • Collections.swap(items, fromPosition, toPosition)
    • items(データリスト)のfromPosition(移動元)とtoPosition(移動先)の要素を入れ替えます。
  • notifyItemMoved(fromPosition, toPosition)
    • RecyclerViewに対して、指定した位置のアイテムが移動したことを通知します。これにより、画面のリスト表示が更新されます。

ビルドしてみると…

【Android】<Kotlin>ItemTouchHelperを使って、リストの項目をスワイプして削除する方法を徹底解説!

アイテムをスワイプすることで、削除できました。

スワイプ中の背景色を変更する方法

ドラッグ中のアイテムの背景色を変更するには、onChildDrawメソッドをオーバーライドします。

override fun onChildDraw(
    c: Canvas,
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    dX: Float,
    dY: Float,
    actionState: Int,
    isCurrentlyActive: Boolean
) {
    val itemView = viewHolder.itemView
    val paint = Paint().apply { color = Color.RED }
    c.drawRect(
        itemView.left.toFloat(),
        itemView.top.toFloat(),
        itemView.right + dX,
        itemView.bottom.toFloat(),
        paint
    )
    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive)
}

10行目:

itemView を使い、スワイプ対象のアイテムの位置とサイズを取得します。

11〜17行目:

  • Paint クラスを使って背景色(赤)を設定。
  • Canvas.drawRect メソッドでアイテムの背後に矩形を描画。
  • 描画範囲は dX の値を基に計算し、スワイプ量に応じてリアルタイムで調整します。

19行目:

super.onChildDraw を呼び出すことで、スワイプ中のアニメーション(アイテムが動く挙動)をそのまま利用します。

ビルドすると、以下のように背景色が変更されています。

【Android】<Kotlin>ItemTouchHelperを使って、リストの項目をスワイプして削除する方法を徹底解説!

まとめ

おつかれさまでした。いかがでしたでしょうか!

RecyclerViewのスワイプ削除機能は、ItemTouchHelperを活用することで簡単に実装できます。
さらに、カスタマイズを加えることで、見た目や操作性を向上させることが可能です。

この記事を参考に、ぜひ実装方法を学んで 活用してみてください!

すだ

技術者としてのキャリアパスを次のレベルへと進めたい皆様、
未経験からIT・Webエンジニアを目指すなら【ユニゾンキャリア】
を通じて、
自分の市場価値をさらに向上させてみませんか?

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

弊社テックブログをご愛読いただきありがとうございます。
当テックブログを運用している株式会社メモリアインクは、
【正社員】還元率83%
【フリーランス】マージン一律5万円で案件のご紹介
と、エンジニアの皆様に分かりやすい形で稼げる仕組みを構築し提供させていただいております。

コメント

コメントする

目次