ドラッグ&ドロップ

Jetpack Compose では、ドラッグ&ドロップで次の 2 つの修飾子がサポートされています。

  • dragAndDropSource: ドラッグ ジェスチャーの開始点としてコンポーザブルを指定します
  • dragAndDropTarget: ドロップされたデータを受け入れるコンポーザブルを指定します。

たとえば、ユーザーがアプリで画像をドラッグできるようにするには、画像コンポーザブルを作成します。 dragAndDropSource 修飾子を追加します。ドロップ ターゲットを設定するには、別のドロップ ターゲットを作成してください dragAndDropTarget 修飾子を追加します。

修飾子は、複数のドラッグ ソースと複数のドロップ ターゲットに適用できます。

修飾子を使用すると、アプリは 2 つ以上のコンポーザブル間でデータを共有できます ClipData を使用します。これは View の実装と相互運用できます。

ドラッグ イベントを開始する

コンポーネント内でドラッグ イベントを有効にするには、dragAndDropSource 修飾子を追加します。 これは suspend 関数をパラメータとして受け取ります。この関数では 呼び出す操作です。dragAndDropSource 修飾子 ポインタ入力イベントを受け取るまで待機してから、ラムダを実行します。 渡されます。ラムダを使用してさまざまな入力イベントを検出します。 たとえば タップや長押しです詳しくは、ポインタ Compose の入力をご覧ください。

ポインタ入力イベントは通常、次のように実装された長押しです。

Modifier.dragAndDropSource {
    detectTapGestures
(onLongPress = {
       
// Transfer data here.
   
})
}

ドラッグ&ドロップ セッションを開始するには、startTransfer() 関数を呼び出します。 このスコープ内で、DragAndDropTransferData を使用して 可能になりますデータはリモート URI、IP アドレスのリッチテキスト データ、 ローカル ファイルなどがありますが、これらはすべて 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 定数のリストをご覧ください。

ドロップデータを受信する

コンポーザブルに dragAndDropTarget 修飾子を割り当て、コンポーザブルを有効にする ドラッグ&ドロップ イベントを受信できます。この修飾子には 2 つのパラメータがあります。1 つ目のパラメータは フィルタとして機能し、修飾子が受け入れることができるデータの種類を指定します。 次にコールバックでデータを配信します

コールバック インスタンスは覚えておく必要があります。次のスニペット コールバックを覚える方法を示します。

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 を返す必要があります。 イベントが拒否され、親コンポーネントに伝播されない場合。

ドラッグ&ドロップ イベントを処理する

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 でのドラッグ&ドロップ