Drag-and-drop

Jetpack Compose unterstützt Drag-and-drop mit zwei Modifikatoren:

  • dragAndDropSource: Gibt eine zusammensetzbare Funktion als Startpunkt der Ziehbewegung an
  • dragAndDropTarget: Gibt eine zusammensetzbare Funktion an, die die gelöschten Daten akzeptiert

Mit den Modifikatoren können Apps Daten zwischen zwei oder mehr zusammensetzbaren Funktionen mithilfe von ClipData teilen, das mit View-Implementierungen interoperabel ist.

Drag-Ereignis starten

Um Drag-Ereignisse innerhalb einer Komponente zu aktivieren, fügen Sie den dragAndDropSource-Modifikator hinzu, der eine Sperrfunktion als Parameter verwendet. Die Funktion definiert die Nutzerinteraktion, mit der der Drag-Vorgang gestartet wird. Der dragAndDropSource-Modifikator wartet, bis er ein Zeigereingabeereignis empfängt, und führt dann die an den Event-Handler übergebene Lambda-Funktion aus. Verwenden Sie Lambda, um eine Vielzahl von Eingabeereignissen zu erkennen, z. B. Tippen oder langes Drücken. Weitere Informationen finden Sie unter Zeigereingabe in Compose.

Das Zeigereingabeereignis wird normalerweise durch langes Drücken so implementiert:

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

Rufen Sie zum Starten einer Drag-and-drop-Sitzung die Funktion startTransfer() auf. Innerhalb dieses Bereichs verwenden Sie DragAndDropTransferData, um die übertragbaren Daten darzustellen. Die Daten können ein Remote-URI, Rich-Text-Daten in der Zwischenablage, eine lokale Datei oder mehr sein. Sie müssen jedoch alle in ein ClipData-Objekt eingeschlossen sein. Geben Sie reinen Text an, zum Beispiel wie folgt:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                )
            )
        )
    })
}

Damit die Ziehaktion über die Grenzen der App hinausgeht, akzeptiert der DragAndDropTransferData-Konstruktor ein flags-Argument. Im folgenden Beispiel gibt die Konstante DRAG_FLAG_GLOBAL an, dass Daten von einer Anwendung in eine andere gezogen werden können:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            DragAndDropTransferData(
                ClipData.newPlainText(
                    "image Url", url
                ),
                flags = View.DRAG_FLAG_GLOBAL
            )
        )
    })
}

DragAndDropTransferData akzeptiert Flags, die vom Android View-System unterstützt werden. Eine vollständige Liste der verfügbaren Flags finden Sie in der Liste der View-Konstanten.

Daten zu Drops erhalten

Weisen Sie einer zusammensetzbaren Funktion den Modifikator dragAndDropTarget zu, damit sie Drag-and-drop-Ereignisse empfangen kann. Der Modifikator hat zwei Parameter: Der erste dient als Filter und gibt die Art der Daten an, die vom Modifikator akzeptiert werden können. Der zweite liefert die Daten in einem Callback.

Die Callback-Instanz sollte gemerkt werden. Das folgende Snippet zeigt, wie Sie sich den Callback merken:

val callback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            // Parse received data
            return true
        }
    }
}

Das nächste Snippet zeigt, wie mit gelöschtem Nur-Text verfahren wird:

Modifier.dragAndDropTarget(
    shouldStartDragAndDrop = { event ->
        event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN)
    }, target = callback
)

Die Callback-Funktion sollte true zurückgeben, wenn das Ereignis genutzt wird, oder false, wenn das Ereignis abgelehnt wird und nicht an die übergeordnete Komponente weitergegeben wird.

Drag-and-drop-Ereignisse verarbeiten

Überschreiben Sie Callbacks in der DragAndDropTarget-Oberfläche, um zu beobachten, wann ein Drag-and-drop-Ereignis eine Komponente startet, endet oder eintritt oder verlässt. So können Sie die UI und das Verhalten der App präzise steuern:

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
}

Weitere Informationen

Codelab: Drag-and-drop in das Feld „Schreiben“ ziehen