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
Loop Engineering これくらいでいい
mikanichinose
0
260
形式手法を使って仕様をコーディングしよう
mikanichinose
0
200
Navigation3でやりとりした画面引数をSavedStateHandleから引き出せない理由
mikanichinose
0
41
Lazy APIを使ってGradleビルド速度を改善する
mikanichinose
1
94
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
770
「脳に収まるコードの書き方」を読んで学んだこと
mikanichinose
1
240
RepositoryのSSoT化
mikanichinose
0
110
Kotlin Multiplatform 始めました
mikanichinose
1
170
Web APIをなぜつくるのか
mikanichinose
0
4.4k
Other Decks in Technology
See All in Technology
パスキーの自動テストはどこまでいけるのか
teamlab
PRO
0
290
ソフトウェア ファクトリー - 再現性のあるソフトウェアの工場づくり / Software factory
iktakahiro
7
5.1k
Browser Spec: Testing Hotwire with Ruby
takahashim
1
130
AI時代のPRレビューにどう向き合うか?
kairim0
1
250
Kiro Crewで「みのるん式」仕事術やってみた
minorun365
PRO
3
880
コンテナ運用におけるネットワーク・コンテナコストの削減方法/How to Reduce Network and Container Costs in Container Operations
masakiokuda
2
320
夫婦で子育てするための育児標準化
codmoninc
PRO
0
470
ストレスなくAIと付き合いたい!こんなときどうしてる?
namiki64
4
630
ブラウザとサーバーから考えるAI時代のフロントエンド監視
shogo4131
3
1k
Rust で関数型ドメインモデリング
takonda
0
170
古い指輪から広がった JAVA コミュニティ とのつながり
yamad
0
130
オントロジーって 結局なにもの? AI エージェントに「意味」を渡す知識設計の話
greenmidori
0
240
Featured
See All Featured
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
330
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
580
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
640
Test your architecture with Archunit
thirion
2
2.4k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
570
The World Runs on Bad Software
bkeepers
PRO
72
12k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
800
The Art of Programming - Codeland 2020
erikaheidi
57
14k
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.4k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
480
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