Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
ComposeでリストUIをDraggableにする方法
Search
mikan
August 23, 2023
Technology
1.7k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ComposeでリストUIをDraggableにする方法
モバチキ 〜Mobile Tips 共有会〜 #1の資料です
https://line.connpass.com/event/292750/
mikan
August 23, 2023
More Decks by mikan
See All by mikan
Navigation3でやりとりした画面引数をSavedStateHandleから引き出せない理由
mikanichinose
0
33
Lazy APIを使ってGradleビルド速度を改善する
mikanichinose
1
92
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
740
「脳に収まるコードの書き方」を読んで学んだこと
mikanichinose
1
240
RepositoryのSSoT化
mikanichinose
0
100
Kotlin Multiplatform 始めました
mikanichinose
1
170
Web APIをなぜつくるのか
mikanichinose
0
4.3k
イベントをどう管理するか
mikanichinose
3
420
ライブラリでしかお目にかかれない珍しい実装
mikanichinose
2
520
Other Decks in Technology
See All in Technology
2026-09-18 gotanda.sre Terraformで複数環境作ったり、複数Stateに分割したりそれとTerragrunt / Terraform multi envs and multi states
masasuzu
4
740
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
190
時うどん〜Socket.getifaddrsで学ぶネットワーク編 / Tokiudon: The Socket.getifaddrs Edition
coe401_
4
270
AIエージェントを安全で速い現場監督にする:Jev・Obsidian・メタハーネス
x5gtrn
PRO
0
120
AIは推し活である。
kurazuuuuuu
2
980
EventBridge に「合流」はない ― サーバーレスのワークフローを育てるということ / No Join in EventBridge
yusukeshimizu
2
560
AI Agent入門〜今更聞けないAgentの話〜
hiromimaganuma
0
120
負債のメタファと2026年 / Debt Metaphor in Agentic Engineering Age 202609 Edition
twada
PRO
13
7.5k
SREへの勘違いに気づいた後の話
tomodakengo
0
160
品質と信頼性を地続きにする
grimoh
2
1k
AIエージェントを最高のパートナーに育てる方法|評価と判断軸を育てる5つのステップ
koichiaoki
1
160
「今盗んで、後で解く」に備える ― AWSのポスト量子暗号入門
yama3133
2
250
Featured
See All Featured
The Cost Of JavaScript in 2023
addyosmani
55
10k
It's Worth the Effort
3n
188
29k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
420
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
590
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
YesSQL, Process and Tooling at Scale
rocio
174
15k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
36k
Chasing Engaging Ingredients in Design
codingconduct
0
340
AI in Enterprises - Java and Open Source to the Rescue
ivargrimstad
0
1.5k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
440
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.6k
Transcript
Compose でリスト UI を Draggable にする方法 モバチキ #1 mikan( 一瀬喜弘)
自己紹介 object Mikan { val name = " 一瀬喜弘" val
company = "karabiner.tech" val hobby = listOf( " 漫画", " アニメ", " ゲーム", " 折り紙", "OSS 開発・コントリビュート", ) }
DroidKaigi へのコントリビュートもしています !
LazyColumn をDraggable にするときの 実装について解説
Demo
難易度別 DraggableUI 1 次元の自由な移動 < 2 次元の自由な移動 <<<<< 1 次元のリスト要素の移動
List 要素のDragAndDrop 実装が なぜ難しいのか
List 要素の DragAndDrop = Reorder だから タップ中の要素の移動 + タップしていない他の要素の移動( 描画上の移動とインデックス
の変更) +( 一番上、下にいったときにスクロールを行う) が発生するから複雑
完成形 https://minurl.deno.dev/3pre5bnkeyp82
実装について詳しく説明するに は時間が足りないので エッセンスだけ共有します
入れ替えを発生されるタイミン グの計算
None
None
None
None
None
None
None
None
複雑な状態の更新をどうやって読み問いていったのか 工作しました
いまいちなポイント firstVisibleItem にさしかかったときだけアニメーションしない overscroll の挙動が硬い
将来的には必要なくなるかも
参考 公式ドキュメント: Drag, swipe, and fling https://developer.android.com/jetpack/compose/touch-input/pointer-input/drag-swipe-fling Google のデモ実装 https://cs.android.com/androidx/platform/frameworks/support/+/androidx-
main:compose/foundation/foundation/integration-tests/foundation- demos/src/main/java/androidx/compose/foundation/demos/LazyColumnDragAndDropDemo.kt Basic Drag-n-Drop in Jetpack Compose ほぼこの実装のパクりですw https://proandroiddev.com/basic-drag-n-drop-in-jetpack-compose-a6919ba58ba8 https://gist.github.com/surajsau/f5342f443352195208029e98b0ee39f3 overscroll(autoscroll という名前で実装にでてくる) の出来は良い https://github.com/aclassen/ComposeReorderable アニメーションはきちんと実装されているけどoverscroll 対応されていない https://github.com/JGomez-Dev/drag-and-drop-compose-library
Appendix
ドラッグジェスチャーのハンドリング : 描画編 ドラッグ中の要素に付けるModifier それ以外の要素に付けるModifier // ドラッグ中の動きを描画 fun Modifier.graphicsLayer(block: GraphicsLayerScope.()
-> Unit): Modifier // これを書かないと要素が動かない Modifier.graphicsLayer { // 垂直方向の描画を更新 translationY = state.itemDisplacement ?: 0f } // 要素の交換が発生し、移動したときにアニメーションさせる Modifier.animateItemPlacement()
ドラッグジェスチャーのハンドリング : 状態更新編 ドラッグイベントを検知して状態更新を行う // タップやロングプレス、ドラッグなどのジェスチャーを処理するための比較的低水準なAPI fun Modifier.pointerInput(key1: Any?, block:
suspend PointerInputScope.() -> Unit): Modifier // 長押しを検知、その後ドラッグイベント毎にonDrach を呼び出す suspend fun PointerInputScope.detectDragGesturesAfterLongPress( onDragStart: (Offset) -> Unit = { }, onDragEnd: () -> Unit = { }, onDragCancel: () -> Unit = { }, onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit ): Unit
ドラッグジェスチャーのハンドリング : 状態更新編 ドラッグイベントを検知して状態更新を行う // タップやロングプレス、ドラッグなどのジェスチャーを処理するための比較的低水準なAPI fun Modifier.pointerInput(key1: Any?, block:
suspend PointerInputScope.() -> Unit): Modifier // 長押しを検知、その後ドラッグイベント毎にonDrach を呼び出す suspend fun PointerInputScope.detectDragGesturesAfterLongPress( onDragStart: (Offset) -> Unit = { }, onDragEnd: () -> Unit = { }, onDragCancel: () -> Unit = { }, onDrag: (change: PointerInputChange, dragAmount: Offset) -> Unit ): Unit // 実際の処理はstate に委譲 detectDragGesturesAfterLongPress( onDrag = { change, dragAmount -> change.consume() state.onDrag(dragAmount) // メインのロジックはこの中に書かれる }, onDragStart = state::onDragStart, // 指の位置からどの要素をタップしているかを取得する onDragEnd = state::onDragInterrupted, // 状態の復元 onDragCancel = state::onDragInterrupted, // 状態の復元 )
ドラッグジェスチャーのハンドリング : 状態更新編 プロパティ 要素の移動距離を保持( 描画のときにつか う) 移動を開始のインデックス( 中断されたと きに復元できるように持っている)
現在のインデックス( 要素の入れ替えが起 こるときに更新) メソッド onDrag ドラッグ距離の更新 要素の交換が必要か判定 要素の交換を実行 必要があればスクロールする checkForOverScroll 見える範囲の先頭/ 末尾に到達したかどうかを判定 class DraggableLazyListState
None