Drag-and-Drop

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

Wenn Sie Nutzern beispielsweise das Ziehen von Bildern in Ihrer App ermöglichen möchten, erstellen Sie ein Bild-Komposit und fügen Sie den Modifikator dragAndDropSource hinzu. Wenn du ein Drop-Ziel einrichten möchtest, erstelle eine weitere Bildkomposition und füge den Modifikator dragAndDropTarget hinzu.

Die Modifikatoren können auf mehrere Ziehquellen und mehrere Drop-Ziele angewendet werden.

Mithilfe der Modifikatoren können Apps Daten über ClipData zwischen zwei oder mehr Composeables teilen. Diese Funktion ist mit View-Implementierungen interoperabel.

Quellelement für Ziehen angeben

Wenn Sie Drag-and-drop-Ereignisse innerhalb einer Komponente aktivieren möchten, fügen Sie die Modifikatortaste dragAndDropSource hinzu. Diese Funktion nimmt eine Funktion als Parameter an. Verwenden Sie in dieser Funktion DragAndDropTransferData, um die übertragbaren Daten darzustellen. Die Daten können ein Remote-URI, Rich-Text-Daten in der Zwischenablage, eine lokale Datei oder andere sein. Sie müssen jedoch in ein ClipData-Objekt eingeschlossen sein. Geben Sie den Text als 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 Konstruktor DragAndDropTransferData 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 Ansicht-Konstanten.

Daten zu Abstürzen erhalten

Weisen Sie einem Composeable den Modifikator dragAndDropTarget zu, damit es Drag-and-drop-Ereignisse empfangen kann. Der Modifikator hat zwei Parameter: Der erste dient als Filter und gibt die Art der Daten an, die der Modifikator akzeptieren kann. Der zweite liefert die Daten in einem Rückruf.

Die Callback-Instanz sollte gespeichert werden. Im folgenden Snippet wird gezeigt, wie der Rückruf gespeichert wird:

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, aktivieren Sie den Empfang über die Schaltfläche requestDragAndDropPermission und deaktivieren Sie ihn dann wieder:

val externalAppCallback = remember {
    object : DragAndDropTarget {
        override fun onDrop(event: DragAndDropEvent): Boolean {
            val permission =
                activity.requestDragAndDropPermissions(event.toAndroidDragEvent())
            // Parse received data
            permission?.release()
            return true
        }
    }
}

Der vom Compose-Callback zurückgegebene DragAndDropEvent unterscheidet sich von dem, der von der requestDragAndDropPermission-Methode erwartet wird. Sie müssen daher die Erweiterungsfunktion toAndroidDragEvent() auf den Parameter anwenden, bevor Sie ihn an die Berechtigungsanfrage übergeben.

Im nächsten Snippet wird gezeigt, wie mit eingefügtem Nur-Text umgegangen wird:

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

Die Rückgabe der Rückruffunktion sollte true sein, 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 DragAndDropTarget-Benutzeroberfläche, um zu erfassen, wann ein Drag-and-drop-Ereignis beginnt, endet oder eine Komponente betritt oder verlässt, um die Benutzeroberfläche und das Verhalten der App genau zu 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