Jetpack Compose では、次の 2 つの修飾子を使用したドラッグ&ドロップがサポートされています。
dragAndDropSource
: コンポーザブルをドラッグ ジェスチャーの開始点として指定します。dragAndDropTarget
: ドロップされたデータを受け入れるコンポーザブルを指定します。
この修飾子により、アプリは ClipData
を使用して 2 つ以上のコンポーザブル間でデータを共有できるようになります。これは View
実装と相互運用できます。
ドラッグ イベントを開始する
コンポーネント内でドラッグ イベントを有効にするには、dragAndDropSource
修飾子を追加します。この修飾子は suspend 関数をパラメータとして受け取ります。この関数は、ドラッグ オペレーションを開始するユーザー操作を定義します。dragAndDropSource
修飾子は、ポインタ入力イベントを受信するまで待機してから、イベント ハンドラに渡されたラムダを実行します。ラムダを使用して、タップや長押しなど、さまざまな入力イベントを検出します。詳しくは、Compose のポインタ入力をご覧ください。
ポインタ入力イベントは通常、次のように実装された長押しです。
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { // Transfer data here. }) }
ドラッグ&ドロップ セッションを開始するには、startTransfer()
関数を呼び出します。このスコープ内で、DragAndDropTransferData
を使用して転送可能なデータを表します。データには、リモート URI、クリップボード上のリッチテキスト データ、ローカル ファイルなどを使用できますが、すべて ClipData
オブジェクトでラップする必要があります。たとえば、次のように書式なしテキストを指定します。
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { startTransfer( DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) ) }) }
ドラッグ アクションがアプリの境界を越えられるようにするために、DragAndDropTransferData
コンストラクタは flags
引数を受け入れます。次の例では、DRAG_FLAG_GLOBAL
定数が、あるアプリから別のアプリにデータをドラッグできることを指定しています。
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { startTransfer( DragAndDropTransferData( ClipData.newPlainText( "image Url", url ), flags = View.DRAG_FLAG_GLOBAL ) ) }) }
DragAndDropTransferData
は、Android View システムがサポートするフラグを受け入れます。使用可能なフラグの一覧については、View 定数のリストをご覧ください。
ドロップ データの受信
dragAndDropTarget
修飾子をコンポーザブルに割り当てて、コンポーザブルがドラッグ&ドロップ イベントを受信できるようにします。修飾子には 2 つのパラメータがあります。1 つ目はフィルタとして機能し、修飾子が受け入れることができるデータの種類を指定します。2 つ目はコールバックでデータを提供します。
コールバック インスタンスは覚えておく必要があります。次のスニペットは、コールバックを記憶する方法を示しています。
val callback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { // Parse received data return true } } }
次のスニペットは、ドロップされた書式なしテキストを処理する方法を示しています。
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback )
コールバック関数は、イベントが消費された場合は true
を返し、イベントが拒否され親コンポーネントに伝播しない場合は false
を返します。
ドラッグ&ドロップ イベントを処理する
UI とアプリの動作を正確に制御するために、ドラッグ&ドロップ イベントの開始、終了、コンポーネントの出入りを監視するように、DragAndDropTarget
インターフェースのコールバックをオーバーライドします。
object : DragAndDropTarget { override fun onStarted(event: DragAndDropEvent) { // When the drag event starts } override fun onEntered(event: DragAndDropEvent) { // When the dragged object enters the target surface } override fun onEnded(event: DragAndDropEvent) { // When the drag event stops } override fun onExited(event: DragAndDropEvent) { // When the dragged object exits the target surface } override fun onDrop(event: DragAndDropEvent): Boolean = true }
参考情報
Codelab: Compose のドラッグ&ドロップ