Drag-and-drop

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

  • dragAndDropSource: Gibt eine zusammensetzbare Funktion als Startpunkt für das Ziehen an.
  • dragAndDropTarget: Gibt eine zusammensetzbare Funktion an, die die gelöschten Daten akzeptiert

Wenn Sie z. B. zulassen möchten, dass Nutzer ein Bild in Ihrer App ziehen können, erstellen Sie eine zusammensetzbare Funktion und fügen Sie den dragAndDropSource-Modifikator hinzu. Erstellen Sie eine weitere zusammensetzbare Bildfunktion und fügen Sie den dragAndDropTarget-Modifikator hinzu, um ein Drop-Ziel einzurichten.

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 zusammensetzbaren Funktionen teilen. Dazu wird ClipData verwendet, das mit View-Implementierungen interoperabel ist.

Drag-Event starten

Wenn Sie Drag-Events innerhalb einer Komponente aktivieren möchten, fügen Sie den dragAndDropSource-Modifikator hinzu. Dieser verwendet eine Unterbrechungsfunktion als Parameter. 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 Lambda-Funktion aus, die an den Event-Handler übergeben wurde. Verwenden Sie Lambda, um eine Vielzahl von Eingabeereignissen wie Tippen oder langes Drücken zu erkennen. Weitere Informationen finden Sie unter Zeigereingabe in „Compose“.

Das Zeigereingabeereignis wird normalerweise wie folgt durch langes Drücken implementiert:

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

Rufen Sie zum Starten einer Drag-and-drop-Sitzung die Funktion startTransfer() auf. Verwenden Sie innerhalb dieses Bereichs DragAndDropTransferData für die übertragbaren Daten. Die Daten können ein Remote-URI, Rich-Text-Daten aus der Zwischenablage, eine lokale Datei oder mehr sein. Sie müssen jedoch alle in einem ClipData-Objekt zusammengefasst werden. Geben Sie nur Text an, z. B. so:

Modifier.dragAndDropSource {
    detectTapGestures(onLongPress = {
        startTransfer(
            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 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 vom Android View-System unterstützte Flags. 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 empfängt. Der Modifikator hat zwei Parameter: Der erste fungiert als Filter und gibt die Art der Daten an, die der Modifikator annehmen kann. Der zweite Parameter liefert die Daten in einem Callback.

Die Callback-Instanz sollte gemerkt werden. Das folgende Snippet zeigt, wie der Callback gespeichert wird:

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

Im nächsten Snippet wird gezeigt, wie mit entferntem Nur-Text umgegangen wird:

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

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

Überschreibe Callbacks in der DragAndDropTarget-Oberfläche, um zu beobachten, wann ein Drag-and-drop-Ereignis beginnt, endet oder in eine Komponente ein- oder beendet wird. So kannst du die Benutzeroberfläche 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
}

Zusätzliche Ressourcen

Codelab: Drag-and-drop in „Schreiben“