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

【Android】<Kotlin>ItemTouchHelperを使って、ドラッグ&ドロップでリスト表示の項目を並び替える方法を徹底解説!

【Android】<Kotlin>ItemTouchHelperを使って、ドラッグ&ドロップでリスト表示の項目を並び替える方法を徹底解説!
すだ

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

本日は、
KotlinのItemTouchHelperを使って
リスト表示の項目をドラッグ&ドロップで並び替えが可能な機能を実装する方法を、
実際のコードを利用して徹底解説していきます!

この記事を読んでわかること…
・ItemTouchHelperとは?
・ドラッグ&ドロップでリスト表示の項目を並び替える実装方法
・ドラッグ中のアイテムの背景色を変更する方法

目次

環境

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

ドラッグ&ドロップの利用シーン

モバイルアプリのドラッグ&ドロップは、以下のようなシーンで利用されます。

  1. タスクリストアプリ:
    • ユーザーがタスクの優先順位を変更したい場合にドラッグ&ドロップで並び替えを行う。
  2. 買い物リストアプリ:
    • 購入アイテムの順序をドラッグで整理。
  3. 音楽プレイリスト:
    • 再生順序を直感的に変更。
  4. 教育アプリ:
    • クイズや並び替え問題のインタラクティブな体験を提供。
  5. 写真やファイル管理:
    • ギャラリーアプリで写真の順番を変更したり、ファイルをフォルダにドラッグして移動。

ドラッグ&ドロップは、便利かつ直感的な操作であるおかげで、ユーザー体験の向上に繋がります。

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 callback = ItemMoveCallback(adapter)
        val itemTouchHelper = ItemTouchHelper(callback)
        itemTouchHelper.attachToRecyclerView(recyclerView)
    }
}

17〜19行目:

  • ItemMoveCallback
    • ドラッグやスワイプの動作を定義したクラスを作成。adapter を渡して、データの並び替えや削除処理を可能にします。
  • ItemTouchHelper
    • 上記の動作定義(callback)を基に、ドラッグ&ドロップを管理する機能を初期化。
  • attachToRecyclerView
    • temTouchHelperRecyclerView に関連付けて、リストのアイテムをドラッグやスワイプで操作できるようにします。

3. ItemMoveCallback.kt

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

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

    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
        return makeMovementFlags(dragFlags, 0)
    }

    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        val fromPosition = viewHolder.adapterPosition
        val toPosition = target.adapterPosition
        adapter.onItemMove(fromPosition, toPosition)
        return true
    }
}

このコードは、RecyclerViewのアイテムをドラッグして並び替えを実現するための カスタムコールバッククラスです。

3行目:

  • getMovementFlags
    • ドラッグやスワイプの方向を指定します。
    • ItemTouchHelper.UP or ItemTouchHelper.DOWN で上下方向のドラッグを許可し、スワイプは無効にしています。

8行目:

  • onMove
    • ドラッグ中にアイテムの位置を変更する処理を実装します。
    • viewHolder.adapterPosition(移動元)とtarget.adapterPosition(移動先)を取得し、アダプターの onItemMove メソッドを呼び出して並び替えを反映します。
    • 戻り値として true を返すことで、操作が完了したことを示します。

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 onItemMove(fromPosition: Int, toPosition: Int) {
        Collections.swap(items, fromPosition, toPosition)
        notifyItemMoved(fromPosition, toPosition)
    }
}

18行目:

このコード(onItemMove)は、RecyclerViewのアイテムをドラッグで並び替える際に、データの順序を入れ替えて画面に反映する処理です。

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

ビルドしてみると…

【Android】<Kotlin>ItemTouchHelperを使って、ドラッグ&ドロップでリスト表示の項目を並び替える方法を徹底解説!

アイテムの順番をドラッグ&ドロップで変更する機能が完成しました。

ドラッグ中のアイテムの背景色を変更する方法

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

override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
    super.onSelectedChanged(viewHolder, actionState)
    if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
        viewHolder?.itemView?.setBackgroundColor(Color.LTGRAY)
    }
}

2〜4行目:

このコードは、RecyclerViewのアイテムがドラッグ操作中であることを視覚的に示す処理を実装しています。

  • onSelectedChanged
    • アイテムの選択状態が変わったときに呼び出されます。
  • actionState == ItemTouchHelper.ACTION_STATE_DRAG
    • ドラッグ操作が開始された場合を判定します。
  • viewHolder?.itemView?.setBackgroundColor(Color.LTGRAY)
    • ドラッグ中のアイテムの背景色をライトグレーに変更します。
override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
    super.clearView(recyclerView, viewHolder)
    viewHolder.itemView.setBackgroundColor(Color.WHITE)
}

2〜3行目:

このコードは、RecyclerViewのアイテムのドラッグ操作が終了したときに背景色をリセットする処理です。

  • clearView
    • ドラッグやスワイプが完了して、アイテムの選択状態が解除されたときに呼び出されます。
  • viewHolder.itemView.setBackgroundColor(Color.WHITE)
    • 背景色を白色(デフォルト)に戻します。

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

【Android】<Kotlin>ItemTouchHelperを使って、ドラッグ&ドロップでリスト表示の項目を並び替える方法を徹底解説!

まとめ

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

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

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

すだ

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

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

この記事を書いた人

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

コメント

コメントする

目次