Trascina

Jetpack Compose supporta il trascinamento con due modificatori:

I modificatori consentono alle app di condividere dati tra due o più elementi componibili utilizzando ClipData, che è interoperabile con le implementazioni di View.

Avviare un evento di trascinamento

Per attivare gli eventi di trascinamento all'interno di un componente, aggiungi il modificatore dragAndDropSource, che assume come parametro una funzione di sospensione. La funzione definisce l'interazione dell'utente che avvia l'operazione di trascinamento. Il modificatore dragAndDropSource attende fino a quando non riceve un evento di input del puntatore, quindi esegue il comando lambda passato al gestore di eventi. Usa la lambda per rilevare vari eventi di input, ad esempio tocchi o pressioni lunghe. Per ulteriori informazioni, consulta Inserimento del puntatore in Compose.

In genere l'evento di input del puntatore richiede una pressione prolungata e viene implementato come segue:

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

Per avviare una sessione di trascinamento, chiama la funzione startTransfer(). All'interno di questo ambito, utilizza DragAndDropTransferData per rappresentare i dati trasferibili. I dati possono essere un URI remoto, dati RTF negli appunti, un file locale o altro ancora, ma devono essere tutti aggregati in un oggetto ClipData. Fornisci un testo normale, ad esempio:

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

Per consentire all'azione di trascinamento di oltre i bordi dell'app, il costruttore DragAndDropTransferData accetta un argomento flags. Nell'esempio seguente, la costante DRAG_FLAG_GLOBAL specifica che i dati possono essere trascinati da un'app all'altra:

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

DragAndDropTransferData accetta i flag supportati dal sistema Android View. Consulta l'elenco delle costanti View per un elenco completo dei flag disponibili.

Ricevi dati sui rilasci

Assegna il modificatore dragAndDropTarget a un componibile per consentirgli di ricevere eventi di trascinamento. Il modificatore ha due parametri: il primo agisce come filtro e specifica il tipo di dati che può accettare, mentre il secondo fornisce i dati in un callback.

Tieni presente che l'istanza di callback deve essere memoria. Lo snippet seguente mostra come ricordare il callback:

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

Lo snippet successivo mostra come gestire il testo normale eliminato:

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

La funzione di callback deve restituire true se l'evento viene consumato oppure false se l'evento viene rifiutato e non si propaga al componente principale.

Gestire gli eventi di trascinamento

Esegui l'override dei callback nell'interfaccia di DragAndDropTarget per osservare quando un evento di trascinamento inizia, termina oppure entra o esce da un componente per un controllo preciso dell'interfaccia utente e del comportamento dell'app:

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
}

Risorse aggiuntive

Codelab: Trascinamento in Compose