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
形式手法を使って仕様をコーディングしよう
mikanichinose
0
160
Navigation3でやりとりした画面引数をSavedStateHandleから引き出せない理由
mikanichinose
0
36
Lazy APIを使ってGradleビルド速度を改善する
mikanichinose
1
92
Navigation3でViewModelにデータを渡す方法
mikanichinose
0
770
「脳に収まるコードの書き方」を読んで学んだこと
mikanichinose
1
240
RepositoryのSSoT化
mikanichinose
0
100
Kotlin Multiplatform 始めました
mikanichinose
1
170
Web APIをなぜつくるのか
mikanichinose
0
4.3k
イベントをどう管理するか
mikanichinose
3
420
Other Decks in Technology
See All in Technology
『GOエコノミー 』(相乗りサービス) におけるスペック駆動開発
mot_techtalk
1
150
猫でもわかるKiro Web
kentapapa
1
160
メルカリにおけるAI時代の高速プロトタイピング基盤「Arca」
ryotarai
18
14k
2026-10-01_MagicPod_QAハーネスエンジニアリングとQA組織の未来像
ynisqa1988
1
280
Apache Iceberg が拓く AI 時代のオープンレイクハウス
tomtanaka
0
210
HolmesGPTで始めるSREエージェント入門!プラットフォームの障害調査はAIにお任せ 〜
sanghyuk
0
250
キャリアLT今日までそして明日から
kentapapa
1
140
プラットフォームを「作る」、 チームに「入り込む」
sansantech
PRO
0
430
[2026 Oracle Technical Deep Dive] AI時代のデータベース基盤をどう選ぶ? Exadata Database Serviceの選択肢と使い分け (2026年9月17日開催)
oracle4engineer
PRO
0
150
データ品質を壊しながらSnowflakeのAIに分析させてみた
kawanago
0
360
AI駆動開発で仕様はどこまで書くべきか? ― 人とAIの責務境界から考える開発プロセスの実践
takahiromatsui
1
280
Incremental HTTP
kazuho
5
1.9k
Featured
See All Featured
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
68
58k
Paper Plane (Part 1)
katiecoart
PRO
2
11k
Optimising Largest Contentful Paint
csswizardry
37
4k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9.2k
Building an army of robots
kneath
307
47k
The #1 spot is gone: here's how to win anyway
tamaranovitovic
4
1.2k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
540
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
290
The World Runs on Bad Software
bkeepers
PRO
72
12k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7k
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