Slide 1

Slide 1 text

Copyright 2022 m.coder All Rights Reserved. 1 Androidでもドラッグ&ドロップがしたい! m.coder

Slide 2

Slide 2 text

Copyright 2022 m.coder All Rights Reserved. 2 自己紹介 m.coder ( @_m_coder ) フラー株式会社所属 Androidテックリード DroidKaigi 2021で「アプリのメンテナンス画面・強制アップ デートを再考する」という発表をしました https://droidkaigi.jp/2021/timetable/276757?day=1 個人ブログ始めました https://nanaten.github.io/blog/

Slide 3

Slide 3 text

Copyright 2022 m.coder All Rights Reserved. 3 こんな要望をもらったことありませんか?

Slide 4

Slide 4 text

Copyright 2022 m.coder All Rights Reserved. 4 「この操作、ドラッグ&ドロップで できるようにならない?」

Slide 5

Slide 5 text

Copyright 2022 m.coder All Rights Reserved. 5 こう言われた時の第一印象は?

Slide 6

Slide 6 text

Copyright 2022 m.coder All Rights Reserved. 6 「やったことない」 「難しそう」

Slide 7

Slide 7 text

Copyright 2022 m.coder All Rights Reserved. 7 (なんとかしてやらない方向に 持っていけないかな)

Slide 8

Slide 8 text

Copyright 2022 m.coder All Rights Reserved. 8 わかります

Slide 9

Slide 9 text

Copyright 2022 m.coder All Rights Reserved. 9 「ホーム画面だと普通にできてるのに…」 「iOSだと並び替え操作あるのに…」

Slide 10

Slide 10 text

Copyright 2022 m.coder All Rights Reserved. 10 ホーム画面 ( Android ) ドラッグ&ドロップで並び替えやフォルダ作成が可能

Slide 11

Slide 11 text

Copyright 2022 m.coder All Rights Reserved. 11 UITableView ( iOS ) ドラッグ&ドロップでリストの並び替えが可能 ※注:内部実装は自前で行う必要あり

Slide 12

Slide 12 text

Copyright 2022 m.coder All Rights Reserved. 12 「あれはOSがやってることなので!」 「iOSはiOS、AndroidはAndroid!」

Slide 13

Slide 13 text

Copyright 2022 m.coder All Rights Reserved. 13 わかります

Slide 14

Slide 14 text

Copyright 2022 m.coder All Rights Reserved. 14 ドラッグ&ドロップ操作ができるアプリ、 パッと思いつかない

Slide 15

Slide 15 text

Copyright 2022 m.coder All Rights Reserved. 15 逆に、実装できるエンジニアは 貴重なのでは?

Slide 16

Slide 16 text

Copyright 2022 m.coder All Rights Reserved. 16 「他の人が実装したことのないUI」を 実装してみませんか?

Slide 17

Slide 17 text

Copyright 2022 m.coder All Rights Reserved. 17 Androidでも ドラッグ&ドロップがしたい!

Slide 18

Slide 18 text

Copyright 2022 m.coder All Rights Reserved. 18 テーマ ● リストのドラッグ&ドロップ操作の概要を知る ● アプリ内のドラッグ&ドロップ ● アプリ間のドラッグ&ドロップ

Slide 19

Slide 19 text

Copyright 2022 m.coder All Rights Reserved. 19 テーマ ● リストのドラッグ&ドロップ操作の概要を知る ● アプリ内のドラッグ&ドロップ ● アプリ間のドラッグ&ドロップ 【ゴール】 ドラッグ&ドロップの実装を(難しそうという理由で) 選択肢から外す人を減らせるといいな

Slide 20

Slide 20 text

01 | RecyclerView のドラッグ&ドロップ 02 | Jetpack DragAndDrop 03 | Jetpack Compose のドラッグ&ドロップって?(オマケ) アジェンダ Copyright 2022 m.coder All Rights Reserved. アジェンダ 20

Slide 21

Slide 21 text

Copyright 2022 m.coder All Rights Reserved. 21 RecyclerViewのドラッグ&ドロップ

Slide 22

Slide 22 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , target: RecyclerView.ViewHolder , ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { /* NO USE */ } } ) itemTouchHelper.attachToRecyclerView(recyclerView) 22 RecyclerViewのドラッグ&ドロップ ItemTouchHelperを使って実装する

Slide 23

Slide 23 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , target: RecyclerView.ViewHolder , ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { /* NO USE */ } } ) itemTouchHelper.attachToRecyclerView(recyclerView) 23 RecyclerViewのドラッグ&ドロップ ItemTouchHelperを使って実装する ItemTouchHelper.SimpleCallbackを利用すると比較的簡単 に実装可能

Slide 24

Slide 24 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , target: RecyclerView.ViewHolder , ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { /* NO USE */ } } ) itemTouchHelper.attachToRecyclerView(recyclerView) 24 RecyclerViewのドラッグ&ドロップ ItemTouchHelperを使って実装する ItemTouchHelper.SimpleCallbackを利用すると比較的簡単 に実装可能

Slide 25

Slide 25 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , target: RecyclerView.ViewHolder , ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { /* NO USE */ } } ) itemTouchHelper.attachToRecyclerView(recyclerView) 25 RecyclerViewのドラッグ&ドロップ ItemTouchHelperを使って実装する ItemTouchHelper.SimpleCallbackを利用すると比較的簡単 に実装可能 最低限override必要なメソッド - onMove - onSwiped(スワイプ操作が必要ない場合でもoverride必 須)

Slide 26

Slide 26 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , target: RecyclerView.ViewHolder , ): Boolean { return true } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { /* NO USE */ } } ) itemTouchHelper.attachToRecyclerView(recyclerView) 26 RecyclerViewのドラッグ&ドロップ ItemTouchHelperを使って実装する ItemTouchHelper.SimpleCallbackを利用すると比較的簡単 に実装可能 最低限override必要なメソッド - onMove - onSwiped(スワイプ操作が必要ない場合でもoverride必 須) attachToRecyclerView でドラッグ操作したい RecyclerView にItemTouchHelper をセットする

Slide 27

Slide 27 text

Copyright 2022 m.coder All Rights Reserved. 27 RecyclerViewのドラッグ&ドロップ ドラッグはできるが…

Slide 28

Slide 28 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper .UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { override fun onMove( … ): Boolean { return true } override fun onMoved( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , fromPos: Int , target: RecyclerView.ViewHolder , toPos: Int , x: Int , y: Int , ) { adapter.notifyItemMoved(fromPos, toPos) } … } ) itemTouchHelper.attachToRecyclerView(recyclerView) 28 RecyclerViewのドラッグ&ドロップ onMoved にドラッグ成功時の処理を書く 左のコードでは adapter.notifyItemMoved() で RecyclerView.Adapterに変更を通知している

Slide 29

Slide 29 text

Copyright 2022 m.coder All Rights Reserved. 29 RecyclerViewのドラッグ&ドロップ リストにドラッグ&ドロップの状態が反映される ※表示上しか反映されていないことに注意。  実際にはViewModelなどのリストを操作して  リストの中身を並び替える必要がある

Slide 30

Slide 30 text

Copyright 2022 m.coder All Rights Reserved. val itemTouchHelper = ItemTouchHelper( object : ItemTouchHelper.SimpleCallback( ItemTouchHelper. UP or ItemTouchHelper. DOWN, ItemTouchHelper. LEFT) { … override fun onSelectedChanged ( viewHolder: RecyclerView.ViewHolder? , actionState: Int , ) { if (actionState == ACTION_STATE_DRAG) { // ドラッグ開始時 viewHolder?.itemView?.alpha = 0.5f } } override fun clearView( recyclerView: RecyclerView , viewHolder: RecyclerView.ViewHolder , ) { // ドラッグ操作終了時 viewHolder.itemView.alpha = 1.0f } … } ) itemTouchHelper.attachToRecyclerView(recyclerView) 30 RecyclerViewのドラッグ&ドロップ onSelectedChanged メソッド ドラッグ操作を開始した際に呼ばれる clearView メソッド ドラッグ操作を終了した際に呼ばれる

Slide 31

Slide 31 text

Copyright 2022 m.coder All Rights Reserved. 31 RecyclerViewのドラッグ&ドロップ ドラッグ開始時と終了時のViewの状態を変えられる

Slide 32

Slide 32 text

Copyright 2022 m.coder All Rights Reserved. 32 RecyclerViewのドラッグ&ドロップ ItemTouchHelperの注意点 onMove, onMoved は他のアイテム上にドラッグされるたび に呼ばれる

Slide 33

Slide 33 text

Copyright 2022 m.coder All Rights Reserved. 33 RecyclerViewのドラッグ&ドロップ ItemTouchHelperの注意点 onMove, onMoved は他のアイテム上にドラッグされるたび に呼ばれる API通信などを行う場合は要注意

Slide 34

Slide 34 text

Copyright 2022 m.coder All Rights Reserved. 34 Jetpack DragAndDrop

Slide 35

Slide 35 text

Copyright 2022 m.coder All Rights Reserved. 35 Jetpack DragAndDrop ● Google I/O 2022 で発表されたJetpackライブラリ ● アプリ内やアプリ間のドラッグ&ドロップ操作をサポー ト ● https://developer.android.com/jetpack/androidx/r eleases/draganddrop

Slide 36

Slide 36 text

Copyright 2022 m.coder All Rights Reserved. 36 Android Viewクラスに対応

Slide 37

Slide 37 text

Copyright 2022 m.coder All Rights Reserved. 37 アプリ内のドラッグ&ドロップ

Slide 38

Slide 38 text

Copyright 2022 m.coder All Rights Reserved. 38 Jetpack DragAndDrop ドラッグする側のView

Slide 39

Slide 39 text

Copyright 2022 m.coder All Rights Reserved. 39 Jetpack DragAndDrop ドロップする側のView

Slide 40

Slide 40 text

Copyright 2022 m.coder All Rights Reserved. 40 Jetpack DragAndDrop ドロップする側のView 現状のDragAndDropライブラリの対象範囲はドロップ側

Slide 41

Slide 41 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 41 Jetpack DragAndDrop DragStartHelperを用いる

Slide 42

Slide 42 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 42 Jetpack DragAndDrop DragStartHelperを用いる 引数にはドラッグ対象のViewとOnDragStartListenerを渡す

Slide 43

Slide 43 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 43 Jetpack DragAndDrop DragStartHelperを用いる 引数にはドラッグ対象のViewとOnDragStartListenerを渡す ドラッグ時のデータの設定を行う

Slide 44

Slide 44 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 44 Jetpack DragAndDrop DragStartHelperを用いる 引数にはドラッグ対象のViewとOnDragStartListenerを渡す ドラッグ時のデータの設定を行う startDragAndDropメソッドを実行する

Slide 45

Slide 45 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 45 Jetpack DragAndDrop DragStartHelperを用いる 引数にはドラッグ対象のViewとOnDragStartListenerを渡す ドラッグ時のデータの設定を行う startDragAndDropメソッドを実行する attach()を呼び出す

Slide 46

Slide 46 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 46 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える

Slide 47

Slide 47 text

Copyright 2022 m.coder All Rights Reserved. 47 ClipData ClipDataについて クリップボードへのデータコピーに用いられるクラス https://developer.android.com/guide/topics/text/copy-p aste https://developer.android.com/reference/android/conte nt/ClipData

Slide 48

Slide 48 text

Copyright 2022 m.coder All Rights Reserved. 48 ClipData ClipDataについて クリップボードへのデータコピーに用いられるクラス https://developer.android.com/guide/topics/text/copy-p aste https://developer.android.com/reference/android/conte nt/ClipData

Slide 49

Slide 49 text

Copyright 2022 m.coder All Rights Reserved. 49 ClipData ClipDataについて クリップボードへのデータコピーに用いられるクラス https://developer.android.com/guide/topics/text/copy-p aste https://developer.android.com/reference/android/conte nt/ClipData

Slide 50

Slide 50 text

Copyright 2022 m.coder All Rights Reserved. 50 ClipData ClipDataについて クリップボードへのデータコピーに用いられるクラス https://developer.android.com/guide/topics/text/copy-p aste https://developer.android.com/reference/android/conte nt/ClipData

Slide 51

Slide 51 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 51 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える

Slide 52

Slide 52 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 52 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える DragShadowBuilderでドラッグ時のViewの描画を設定

Slide 53

Slide 53 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 53 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える DragShadowBuilderでドラッグ時のViewの描画を設定 startDragAndDropの引数 ・ClipData ・DragShadowBuilder ・myLocalState(Object型) ・ドラッグ時の権限フラグ

Slide 54

Slide 54 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 54 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える DragShadowBuilderでドラッグ時のViewの描画を設定 startDragAndDropの引数 ・ClipData ・DragShadowBuilder ・myLocalState(Object型) ・ドラッグ時の権限フラグ

Slide 55

Slide 55 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val uri = Uri.parse( “{cat_image_uri}” ) val dragData = ClipData( "image", arrayOf("image/*"), ClipData.Item(uri) ) val builder = View.DragShadowBuilder(v) v.startDragAndDrop( dragData, builder, null, 0, ) } ).attach() 55 Jetpack DragAndDrop OnDragStartListener ClipData型のデータを扱える DragShadowBuilderでドラッグ時のViewの描画を設定 startDragAndDropの引数 ・ClipData ・DragShadowBuilder ・myLocalState(Object型) ・ドラッグ時の権限フラグ

Slide 56

Slide 56 text

Copyright 2022 m.coder All Rights Reserved. DropHelper.configureView( requireActivity() , dropImageView, arrayOf("text/plain", "image/*"), OnReceiveContentListener { _, payload -> // 受け取ったPayloadの処理 payload } ) 56 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う

Slide 57

Slide 57 text

Copyright 2022 m.coder All Rights Reserved. DropHelper.configureView( requireActivity() , dropImageView, arrayOf("text/plain", "image/*"), OnReceiveContentListener { _, payload -> // 受け取ったPayloadの処理 payload } ) 57 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う

Slide 58

Slide 58 text

Copyright 2022 m.coder All Rights Reserved. DropHelper.configureView( requireActivity() , dropImageView, arrayOf("text/plain", "image/*"), OnReceiveContentListener { _, payload -> // 受け取ったPayloadの処理 payload } ) 58 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う

Slide 59

Slide 59 text

Copyright 2022 m.coder All Rights Reserved. DropHelper.configureView( requireActivity() , dropImageView, arrayOf("text/plain", "image/*"), OnReceiveContentListener { _, payload -> // 受け取ったPayloadの処理 payload } ) 59 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う OnReceiveContentListenerで 受け取ったデータに応じた処理を行う

Slide 60

Slide 60 text

Copyright 2022 m.coder All Rights Reserved. DropHelper.configureView( requireActivity() , dropImageView, arrayOf("text/plain", "image/*"), OnReceiveContentListener { _, payload -> val clip: ClipData = payload. clip when (clip.description.getMimeType(0)) { "text/plain" -> { // トースト表示 } "image/*" -> { val uri = clip.getItemAt( 0).uri dropImageView.setImageURI(uri) } } payload } ) 60 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う OnReceiveContentListenerで 受け取ったデータに応じた処理を行う

Slide 61

Slide 61 text

Copyright 2022 m.coder All Rights Reserved. 61 Jetpack DragAndDrop DropHelper Jetpack DragAndDropで追加されたHelper configreView() でドロップさせたいViewに設定を行う OnReceiveContentListenerで 受け取ったデータに応じた処理を行う ドラッグ&ドロップが可能になる

Slide 62

Slide 62 text

Copyright 2022 m.coder All Rights Reserved. 62 アプリ間のドラッグ&ドロップ

Slide 63

Slide 63 text

Copyright 2022 m.coder All Rights Reserved. 63 Jetpack DragAndDrop アプリ間のドラッグ&ドロップ

Slide 64

Slide 64 text

Copyright 2022 m.coder All Rights Reserved. 64 Jetpack DragAndDrop アプリ間ドラッグ&ドロップの準備 1. startDragAndDrop のフラグ設定

Slide 65

Slide 65 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> // 省略 ClipDataの生成などなど … v.startDragAndDrop( dragData, builder, null, DRAG_FLAG_GLOBAL or DRAG_FLAG_GLOBAL_URI_READ ) } ).attach() 65 Jetpack DragAndDrop startDragAndDropに DRAG_FLAG_GLOBAL を指定するとアプリ間ドラッグ&ドロップが可能になる DRAG_FLAG_GLOBAL_URI_READ を指定するとURIの読み取りが可能になる

Slide 66

Slide 66 text

Copyright 2022 m.coder All Rights Reserved. 66 Jetpack DragAndDrop アプリ間ドラッグ&ドロップの準備 2. FileProviderやContentProviderを用いたURIの外部公開

Slide 67

Slide 67 text

Copyright 2022 m.coder All Rights Reserved. 67 Jetpack DragAndDrop FileProvider・ContentProvider? →アプリ間でコンテンツを共有するためのクラス 外部アプリからURIを使ったアクセスを可能にする

Slide 68

Slide 68 text

Copyright 2022 m.coder All Rights Reserved. 68 Jetpack DragAndDrop FileProvider、ContentProviderについては 省略します  参考: https://developer.android.com/training/secure-file-sharing/setup-sharing https://developer.android.com/guide/topics/providers/content-provider-basics

Slide 69

Slide 69 text

Copyright 2022 m.coder All Rights Reserved. DragStartHelper( imageView, DragStartHelper.OnDragStartListener { v, _ -> val bitmap = imageView.drawToBitmap() val fileName = "sample_photo.jpg" val tempFile = File( "{file_path}", fileName) // 省略 一時ファイルにFileOutputStream を用いて書き込み val uri = FileProvider.getUriForFile( requireContext() , BuildConfig.APPLICATION_ID + ".provider", tempFile ) // 省略 ClipDataの生成などなど … v.startDragAndDrop( dragData, builder, null, DRAG_FLAG_GLOBAL or DRAG_FLAG_GLOBAL_URI_READ ) } ).attach() 69 Jetpack DragAndDrop FileProviderやContentProviderなどを用いて、URIを適切に 外部アプリから読み取れるようにする

Slide 70

Slide 70 text

Copyright 2022 m.coder All Rights Reserved. 70 Jetpack DragAndDrop アプリ間ドラッグ&ドロップDone!

Slide 71

Slide 71 text

Copyright 2022 m.coder All Rights Reserved. 71 【小ネタ】 Jetpack Composeの ドラッグ&ドロップ…?

Slide 72

Slide 72 text

Copyright 2022 m.coder All Rights Reserved. 72 まだです

Slide 73

Slide 73 text

Copyright 2022 m.coder All Rights Reserved. Modifier.pointerInput(Unit) { detectDragGestures( onDrag = { /* ドラッグ */ }, onDragStart = { /* ドラッグ開始 */ }, onDragEnd = { /* ドラッグ終了 */ }, onDragCancel = { /* ドラッグキャンセル */ } ) } 73 Jetpack Compose detectDragGestures ドラッグ操作の検出は可能そう それ以上の操作は全て自前でやる必要がありそう

Slide 74

Slide 74 text

Copyright 2022 m.coder All Rights Reserved. 74 Jetpack Composeのドラッグ&ドロップ ロードマップには載っている https://developer.android.google.cn/jetpack/androidx/c ompose-roadmap

Slide 75

Slide 75 text

Copyright 2022 m.coder All Rights Reserved. 75 まとめ ● ItemTouchHelper ○ リストの並び替えを実装したい時 ● Jetpack DragAndDrop ○ リスト以外のUIでドラッグ&ドロップを実装したい時 ○ アプリ間のドラッグ&ドロップを実装したい時 ● Jetpack Composeのドラッグ&ドロップ ○ もう少し待つ必要がありそう

Slide 76

Slide 76 text

Copyright 2022 m.coder All Rights Reserved. 76 おわり