Jetpack Compose supporta il trascinamento con due modificatori:
dragAndDropSource
: specifica un composable come punto di partenza del gesto di trascinamentodragAndDropTarget
: specifica un composable che accetta i dati dropped
Ad esempio, per consentire agli utenti di trascinare un'immagine nella tua app, crea un componibile di immagini e aggiungi il modificatore dragAndDropSource
. Per impostare un target di rilascio,
crea un'altra composizione di immagini e aggiungi il modificatore dragAndDropTarget
.
I modificatori possono essere applicati a più origini di trascinamento e a più destinazioni di rilascio.
I modificatori consentono alle app di condividere dati tra due o più composabili utilizzando
ClipData
, che è interoperabile con le implementazioni di View
.
Specifica un'origine di trascinamento
Per attivare gli eventi di trascinamento all'interno di un componente, aggiungi il modificatore dragAndDropSource
.
Questa funzione accetta una funzione come parametro. All'interno di questa funzione, utilizza
DragAndDropTransferData
per rappresentare i dati trasferibili. I dati possono essere un URI remoto, dati di testo avanzato negli appunti, un file locale e altro ancora, ma devono essere tutti racchiusi in un oggetto ClipData
. Fornisci testo normale, ad esempio come segue:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ) ) }
Per consentire all'azione di trascinamento di superare i confini dell'app, il
costruttore DragAndDropTransferData
accetta un argomento flags
. Nel
seguente esempio, la costante DRAG_FLAG_GLOBAL
specifica che i dati possono essere trascinati da un'app all'altra:
Modifier.dragAndDropSource { _ -> DragAndDropTransferData( ClipData.newPlainText( "image Url", url ), flags = View.DRAG_FLAG_GLOBAL ) }
DragAndDropTransferData
accetta i flag supportati dal sistema di visualizzazione Android.
Consulta l'elenco delle costanti View per un elenco esaustivo dei flag disponibili.
Ricevere i dati sui cali
Assegna il modificatore dragAndDropTarget
a un composable per consentirgli di ricevere eventi di trascinamento. Il modificatore ha due parametri: il primo funge da filtro e specifica il tipo di dati che può accettare, mentre il secondo invia i dati in un callback.
Tieni presente che l'istanza di callback deve essere memorizzata. Lo snippet riportato di seguito mostra come ricordare la chiamata di ritorno:
val callback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { // Parse received data return true } } }
Per accettare i dati da altre app, usa requestDragAndDropPermission
per attivare la ricezione e rilascia il pulsante al termine:
val externalAppCallback = remember { object : DragAndDropTarget { override fun onDrop(event: DragAndDropEvent): Boolean { val permission = activity.requestDragAndDropPermissions(event.toAndroidDragEvent()) // Parse received data permission?.release() return true } } }
È importante ricordare che il valore DragAndDropEvent
restituito dal callback Compose è diverso da quello previsto dal metodo requestDragAndDropPermission
, pertanto devi chiamare la funzione di estensione toAndroidDragEvent()
sul parametro prima di passarlo alla richiesta di autorizzazione.
Lo snippet seguente mostra come gestire il testo normale inserito:
Modifier.dragAndDropTarget( shouldStartDragAndDrop = { event -> event.mimeTypes().contains(ClipDescription.MIMETYPE_TEXT_PLAIN) }, target = callback // or externalAppCallback )
La funzione di callback deve restituire true
se l'evento viene utilizzato o false
se l'evento viene rifiutato e non si propaga al componente principale.
Gestire gli eventi di trascinamento
Sostituisci i callback nell'interfaccia DragAndDropTarget
per osservare quando un evento di trascinamento inizia, termina o 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: Trascina in Scrittura