Jetpack Compose supporta il trascinamento con due modificatori:
dragAndDropSource
: specifica un componibile come punto iniziale del gesto di trascinamentodragAndDropTarget
: specifica un componibile che accetta i dati eliminati
Ad esempio, per consentire agli utenti di trascinare un'immagine nella tua app, crea un'immagine componibile e aggiungi il modificatore dragAndDropSource
. Per configurare un target di rilascio, crea un'altra immagine componibile e aggiungi il modificatore dragAndDropTarget
.
I modificatori possono essere applicati a più origini di trascinamento e a più obiettivi di rilascio.
I modificatori consentono alle app di condividere dati tra due o più componibili
utilizzando ClipData
, 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 una funzione di sospensione come parametro. La funzione definisce l'interazione dell'utente
che avvia l'operazione di trascinamento. Il modificatore dragAndDropSource
attende finché non riceve un evento di input del puntatore, quindi esegue la funzione lambda
passata al gestore di eventi. Usa il comando lambda per rilevare diversi
eventi di input, ad esempio tocchi o pressioni lunghe. Per maggiori informazioni, vedi Input del puntatore in Compose.
L'evento di input del puntatore viene in genere implementato con una pressione prolungata nel seguente modo:
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 testo normale, ad esempio, come segue:
Modifier.dragAndDropSource { detectTapGestures(onLongPress = { startTransfer( DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) ) }) }
Per consentire all'azione di trascinamento di oltrepassare 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 flag supportati dal sistema Android View. Consulta
l'elenco delle costanti View per un elenco esaustivo dei flag disponibili.
Ricevi dati relativi al lancio
Assegna il modificatore dragAndDropTarget
a un componibile per consentire a quest'ultimo di ricevere eventi di trascinamento. Il modificatore ha due parametri: il primo agisce da filtro e specifica il tipo di dati che può accettare, mentre il secondo fornisce i dati in un callback.
Tieni presente che devi ricordare l'istanza di callback. Il seguente snippet 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 dovrebbe restituire true
se l'evento viene consumato o 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 o entra o esce da un componente in modo da avere 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: trascina in Compose