[Android]Composeでグリッドのドラッグアンドドロップをやってみる

エンジニア

Androidのjetpack composeでグリッドのドラッグアンドドロップをやってみた。

仕事でグリッドでのドラッグアンドドロップの実装をすることになるかもしれないのだが、jetpack compose自体はドラッグアンドドロップができるようなリストやグリッドは提供していないらしい。

というわけで、どんな感じで実装するのが良いのかを試してみた。

巷にあまり情報がないので、まずはChatGPTに相談しつつ調べてみたところ、基本的にドラッグアンドドロップは以下で実現できるらしい。

  • ドラッグ対象のCompose要素にModifier.pointerInputを追加
  • pointerInput内でdetectDragGesturesなどのジェスチャー検出関数でドラッグを検知
  • ドラッグ中の要素の位置を更新するロジックを実装

今回はグリッドにボタンが並んだようなUIが作りたかったので、

グリッドの実現にはLazyVerticalGridを採用。

リストのロジック

グリッドには何らか関心のオブジェクトのListを渡す想定。

ドラッグアンドドロップにより、リストの操作が必要になるため、それを実現するためのリストクラスを作成。

紆余曲折あって、試行錯誤した結果最終的にドラッグ中のindexのオブジェクトを移動先のindexへ移動、空いたスペースを詰めるという挙動で落ち着いた。最終的にあえてクラスにするまでもなかったかもしれない。

class MovableList<T>(private val list: MutableList<T>) : MutableList<T> by list {
    fun move(from: Int, to: Int): Int {
        if (from < 0 || from >= size) return -1
        if (to < 0 || to > size) return -1
        if (to == from) return -1

        val item = list.removeAt(from)
        val indexToAdd = if (to > size) size else to
        list.add(indexToAdd, item)
        return indexToAdd
    }
}

時間があまりないので一旦これだけ。

最終的にはこんな感じで、DraggableGridStateとDraggableGridというComposableを作成。

これでも試行錯誤していくなかで意外とロジックはシンプルになった。

TilAndroid/app/src/main/java/net/uoneweb/android/til/ui/buttons/draggablegrid/DraggableGrid.kt at main · u-one/TilAndroid
Contribute to u-one/TilAndroid development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました