Jetpack Compose unterstützt Drag-and-drop mit zwei Modifikatoren:
dragAndDropSource: Gibt eine komponierbare Funktion als Startpunkt der Ziehgeste an.dragAndDropTarget: Gibt eine zusammensetzbare Funktion an, die die abgelegten Daten akzeptiert.
Wenn Sie beispielsweise Nutzern ermöglichen möchten, ein Bild in Ihrer App zu ziehen, erstellen Sie eine komponierbare Funktion für Bilder und fügen Sie den Modifikator dragAndDropSource hinzu. Wenn Sie ein Ablageziel einrichten möchten, erstellen Sie ein weiteres Bild-Composable und fügen Sie den Modifikator dragAndDropTarget hinzu.
Die Modifikatoren können auf mehrere Drag-Quellen und mehrere Drop-Ziele angewendet werden.
Mit den Modifikatoren können Apps Daten zwischen zwei oder mehr Composables mithilfe von ClipData teilen, das mit View-Implementierungen interoperabel ist.
Drag-Quelle angeben
Wenn Sie Drag-Events innerhalb einer Komponente aktivieren möchten, fügen Sie den Modifikator dragAndDropSource hinzu.
Diese verwendet eine Funktion als Parameter. Verwenden Sie in dieser Funktion DragAndDropTransferData, um die übertragbaren Daten darzustellen. Die Daten können ein Remote-URI, RTF-Daten in der Zwischenablage, eine lokale Datei oder etwas anderes sein, müssen aber alle in einem ClipData-Objekt verpackt sein. Geben Sie Nur-Text an, z. B. so:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
Damit die Ziehaktion die Grenzen der App überschreiten kann, akzeptiert der DragAndDropTransferData-Konstruktor ein flags-Argument. Im folgenden Beispiel gibt die Konstante DRAG_FLAG_GLOBAL an, dass Daten von einer App in eine andere gezogen werden können:
Modifier.dragAndDropSource { _ -> 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.
Drop-Daten empfangen
Weisen Sie einer zusammensetzbaren Funktion den Modifikator dragAndDropTarget zu, damit sie Drag-and-Drop-Ereignisse empfangen kann. Der Modifikator hat zwei Parameter: Der erste fungiert als Filter und gibt die Art der Daten an, die der Modifikator akzeptieren kann. Der zweite liefert die Daten in einem Callback.
Die Callback-Instanz sollte gespeichert 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 } } }
Wenn Sie Daten von anderen Apps akzeptieren möchten, verwenden Sie den requestDragAndDropPermission, um den Empfang zu aktivieren, und geben Sie ihn frei, wenn Sie fertig sind:
val externalAppCallback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { val permission = activity.requestDragAndDropPermissions(event.toAndroidDragEvent()) // Parse received data permission?.release() return true } } }
Wichtig: Der vom Compose-Callback zurückgegebene DragAndDropEvent unterscheidet sich von dem, der von der Methode requestDragAndDropPermission erwartet wird. Sie müssen daher die Erweiterungsfunktion toAndroidDragEvent() für den Parameter aufrufen, bevor Sie ihn an die Berechtigungsanfrage übergeben.
Das nächste Snippet zeigt, wie abgelegter Nur-Text verarbeitet wird:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
Die Callback-Funktion sollte true zurückgeben, wenn das Ereignis verarbeitet 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 Schnittstelle DragAndDropTarget, um zu beobachten, wann ein Drag-and-Drop-Ereignis beginnt, endet oder eine Komponente betritt oder verlässt. So können Sie die Benutzeroberfläche und das Verhalten der App genau 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 }
Zusätzliche Ressourcen
Codelab: Drag and Drop in Compose