Le sezioni seguenti illustrano alcuni concetti chiave per il processo di trascinamento.
Processo di trascinamento
Il processo di trascinamento prevede quattro passaggi o stati: avviato, in corso, rilasciato e terminato.
- Avviata
In risposta a un gesto di trascinamento dell'utente, l'applicazione chiama
startDragAndDrop()per indicare al sistema di avviare un'operazione di trascinamento. Gli argomenti del metodo forniscono quanto segue:- I dati da trascinare.
- Un callback per disegnare l'ombra di trascinamento
- I metadati che descrivono i dati trascinati
- Il sistema risponde richiamando l'applicazione per ottenere un'ombra di trascinamento. Il sistema visualizza quindi l'ombra di trascinamento sul dispositivo.
- Successivamente, il sistema invia un evento di trascinamento con il tipo di azione
ACTION_DRAG_STARTEDal listener di eventi di trascinamento di tutti gli oggettiViewnel layout corrente. Per continuare a ricevere eventi di trascinamento, incluso un possibile evento di rilascio, il listener di eventi di trascinamento deve restituiretrue. In questo modo, il listener viene registrato nel sistema. Solo i listener registrati continuano a ricevere eventi di trascinamento. A questo punto, i listener possono anche modificare l'aspetto dell'oggettoViewdella destinazione di rilascio per mostrare che la visualizzazione può accettare un evento di rilascio. - Se il listener di eventi di trascinamento restituisce
false, non riceve eventi di trascinamento per l'operazione corrente finché il sistema non invia un evento di trascinamento con il tipo di azioneACTION_DRAG_ENDED. Restituendofalse, il listener indica al sistema che non è interessato all'operazione di trascinamento e non vuole accettare i dati trascinati.
- Operazione in corso…
- L'utente continua a trascinare. Quando l'ombra di trascinamento interseca il riquadro di delimitazione di una destinazione di rilascio, il sistema invia uno o più eventi di trascinamento al listener di eventi di trascinamento della destinazione. Il listener potrebbe modificare l'aspetto della
Viewdella destinazione di rilascio in risposta all'evento. Ad esempio, se l'evento indica che l'ombra di trascinamento entra nel riquadro di delimitazione della destinazione di rilascio (tipo di azioneACTION_DRAG_ENTERED), il listener può reagire evidenziando laView. - Rilasciato
- L'utente rilascia l'ombra di trascinamento all'interno del riquadro di delimitazione di una destinazione di rilascio. Il sistema invia al listener della destinazione di rilascio un evento di trascinamento con action
type
ACTION_DROP. L'oggetto evento di trascinamento contiene i dati che vengono passati al sistema nella chiamata astartDragAndDrop()che avvia l'operazione. Il listener deve restituire il valore booleanotrueal sistema se elabora correttamente i dati rilasciati. : questo passaggio si verifica solo se l'utente rilascia l'ombra di trascinamento all'interno del riquadro di delimitazione di unaViewil cui listener è registrato per ricevere eventi di trascinamento (una destinazione di rilascio). Se l'utente rilascia l'ombra di trascinamento in qualsiasi altra situazione, non viene inviato alcun evento di trascinamentoACTION_DROP. - Terminata
Dopo che l'utente ha rilasciato l'ombra di trascinamento e dopo che il sistema ha inviato
un evento di trascinamento con il tipo di azione
ACTION_DROP, se necessario, il sistema invia un evento di trascinamento con il tipo di azioneACTION_DRAG_ENDEDper indicare che l'operazione di trascinamento è terminata. Questa operazione viene eseguita indipendentemente dalla posizione in cui l'utente rilascia l'ombra di trascinamento. L'evento viene inviato a ogni listener registrato per ricevere eventi di trascinamento, anche se il listener riceve anche l'eventoACTION_DROP.
Ognuno di questi passaggi è descritto in modo più dettagliato nella sezione chiamata Operazione di trascinamento.
Eventi di trascinamento
Il sistema invia un evento di trascinamento sotto forma di oggetto DragEvent, che contiene un tipo di azione che descrive cosa sta succedendo nel processo di trascinamento. A seconda del tipo di azione, l'oggetto può contenere anche altri dati.
I listener di eventi di trascinamento ricevono l'oggetto DragEvent. Per ottenere il tipo di azione,
i listener chiamano
DragEvent.getAction().
Esistono sei possibili valori definiti da costanti nella classe DragEvent, descritti nella Tabella 1:
Tabella 1. Tipi di azione DragEvent
| Tipo di azione | Significato |
|---|---|
ACTION_DRAG_STARTED |
L'applicazione chiama startDragAndDrop() e ottiene
un'ombra di trascinamento. Se il listener vuole continuare a ricevere eventi di trascinamento
per questa operazione, deve restituire il valore booleano true al
sistema.
|
ACTION_DRAG_ENTERED |
L'ombra di trascinamento entra nel riquadro di delimitazione del listener di eventi di trascinamento
View. Questo è il primo tipo di azione evento che il listener
riceve quando l'ombra di trascinamento entra nel riquadro di delimitazione.
|
ACTION_DRAG_LOCATION |
Dopo un
ACTION_DRAG_ENTERED evento, l'ombra di trascinamento si trova ancora
all'interno del riquadro di delimitazione del listener di eventi di trascinamento
View.
|
ACTION_DRAG_EXITED |
Dopo un ACTION_DRAG_ENTERED e almeno un
ACTION_DRAG_LOCATION evento, l'ombra di trascinamento si sposta
all'esterno del riquadro di delimitazione del listener di eventi di trascinamento
View.
|
ACTION_DROP |
L'ombra di trascinamento viene rilasciata sul listener di eventi di trascinamento
View. Questo tipo di azione viene inviato al listener di un oggetto View
solo se il listener restituisce il valore booleano
true in risposta all'
ACTION_DRAG_STARTED evento di trascinamento. Questo tipo di azione non viene
inviato se l'utente rilascia l'ombra di trascinamento su un View
il cui listener non è registrato o se l'utente rilascia l'ombra di
trascinamento su qualsiasi elemento che non fa parte del layout corrente.
Il listener restituisce il valore booleano |
ACTION_DRAG_ENDED |
Il sistema sta terminando l'operazione di trascinamento. Questo tipo di azione
non è necessariamente preceduto da un evento ACTION_DROP. Se
il sistema invia un ACTION_DROP, la ricezione del
tipo di azione ACTION_DRAG_ENDED non implica che il
rilascio sia andato a buon fine. Il listener deve chiamare
getResult(),
come mostrato nella Tabella 2, per ottenere il valore restituito in risposta a ACTION_DROP. Se non viene inviato un
ACTION_DROP evento, allora
getResult() restituisce false.
|
L'oggetto DragEvent contiene anche i dati e i metadati che l'applicazione fornisce al sistema nella chiamata a startDragAndDrop(). Alcuni dati sono validi solo per determinati tipi di azione, come riassunto nella Tabella 2. Per ulteriori informazioni sugli eventi e sui dati associati, vedi la sezione chiamata A
Operazione di trascinamento.
Tabella 2. Dati DragEvent validi per tipo di azione
getAction()valore |
getClipDescription()valore |
getLocalState()valore |
getX()valore |
getY()valore |
getClipData()valore |
getResult()valore |
|---|---|---|---|---|---|---|
ACTION_DRAG_STARTED |
✓ | ✓ | ||||
ACTION_DRAG_ENTERED |
✓ | ✓ | ||||
ACTION_DRAG_LOCATION |
✓ | ✓ | ✓ | ✓ | ||
ACTION_DRAG_EXITED |
✓ | ✓ | ||||
ACTION_DROP |
✓ | ✓ | ✓ | ✓ | ✓ | |
ACTION_DRAG_ENDED |
✓ | ✓ |
I metodi DragEvent getAction(),
describeContents(),
writeToParcel(),
e toString() restituiscono sempre dati validi.
Se un metodo non contiene dati validi per un determinato tipo di azione, restituisce null o 0, a seconda del tipo di risultato.
Ombra di trascinamento
Durante un'operazione di trascinamento, il sistema visualizza un'immagine che l'utente trascina. Per lo spostamento dei dati, questa immagine rappresenta i dati trascinati. Per altre operazioni, l'immagine rappresenta un aspetto dell'operazione di trascinamento.
L'immagine è chiamata ombra di trascinamento. Puoi crearla con i metodi dichiarati per
un
View.DragShadowBuilder
oggetto. Passa il builder al sistema quando avvii un'operazione di trascinamento utilizzando startDragAndDrop(). Come parte della risposta a startDragAndDrop(), il sistema richiama i metodi di callback definiti in View.DragShadowBuilder per ottenere un'ombra di trascinamento.
La classe View.DragShadowBuilder ha due costruttori:
View.DragShadowBuilder(View)Questo costruttore accetta qualsiasi oggetto
Viewdell'applicazione. Il costruttore memorizza l'oggettoViewnell'oggettoView.DragShadowBuilder, in modo che i callback possano accedervi per costruire l'ombra di trascinamento. La visualizzazione non deve essere unaViewselezionata dall'utente per avviare l'operazione di trascinamento.Se utilizzi questo costruttore, non devi estendere
View.DragShadowBuildero sostituire i relativi metodi. Per impostazione predefinita, ottieni un'ombra di trascinamento con lo stesso aspetto dellaViewpassata come argomento, centrata sotto la posizione in cui l'utente tocca lo schermo.View.DragShadowBuilder()Se utilizzi questo costruttore, nell'oggetto
View.DragShadowBuildernon è disponibile alcun oggettoView. Il campo è impostato sunull. Devi estendereView.DragShadowBuildere sostituire i relativi metodi, altrimenti ottieni un'ombra di trascinamento invisibile. Il sistema non genera un errore.
La classe View.DragShadowBuilder ha due metodi che insieme creano l'ombra di trascinamento:
onProvideShadowMetrics()Il sistema chiama questo metodo immediatamente dopo la chiamata a
startDragAndDrop(). Utilizza il metodo per inviare le dimensioni e il punto di contatto dell'ombra di trascinamento al sistema. Il metodo ha due parametri:outShadowSize: unPointoggetto. La larghezza dell'ombra di trascinamento va inxe la sua altezza iny.outShadowTouchPoint: un oggettoPoint. Il punto di contatto è la posizione all'interno dell'ombra di trascinamento che deve trovarsi sotto il dito dell'utente durante il trascinamento. La posizione X va inxe la posizione Y iny.onDrawShadow()Immediatamente dopo la chiamata a
onProvideShadowMetrics(), il sistema chiamaonDrawShadow()per creare l'ombra di trascinamento. Il metodo ha un singolo argomento, un oggettoCanvasche il sistema costruisce dai parametri forniti inonProvideShadowMetrics(). Il metodo disegna l'ombra di trascinamento sulCanvasfornito.
Per migliorare le prestazioni, mantieni le dimensioni dell'ombra di trascinamento ridotte. Per un singolo elemento, potresti utilizzare un'icona. Per una selezione di più elementi, potresti utilizzare le icone in una pila anziché immagini complete distribuite sullo schermo.
Listener di eventi di trascinamento e metodi di callback
Un View riceve eventi di trascinamento con un listener di eventi di trascinamento che implementa
View.OnDragListener o con il metodo di callback onDragEvent() della visualizzazione. Quando
il sistema chiama il metodo o il listener, fornisce un
DragEvent argomento.
Nella maggior parte dei casi, è preferibile utilizzare un listener anziché il metodo di callback. Quando progetti le UI, in genere non crei sottoclassi delle classi View, ma l'utilizzo del metodo di callback ti costringe a creare sottoclassi per sostituire il metodo. Al contrario, puoi implementare una classe listener e poi utilizzarla con più oggetti View diversi. Puoi anche implementarla come classe inline anonima o espressione lambda. Per impostare il listener per un oggetto View, chiama setOnDragListener().
In alternativa, puoi modificare l'implementazione predefinita di onDragEvent() senza sostituire il metodo. Imposta un
OnReceiveContentListener
su una visualizzazione. Per maggiori dettagli, vedi
setOnReceiveContentListener().
Il metodo onDragEvent() esegue quindi le seguenti operazioni per impostazione predefinita:
- Restituisce true in risposta alla chiamata a
startDragAndDrop(). Chiama
performReceiveContent()se i dati di trascinamento vengono rilasciati nella visualizzazione. I dati vengono passati al metodo comeContentInfooggetto. Il metodo richiamaOnReceiveContentListener.Restituisce true se i dati di trascinamento vengono rilasciati nella visualizzazione e
OnReceiveContentListenerutilizza parte dei contenuti.
Definisci il OnReceiveContentListener per gestire i dati in modo specifico per la tua
app. Per la compatibilità con le versioni precedenti fino al livello API 24, utilizza la versione Jetpack di
OnReceiveContentListener.
Puoi avere un listener di eventi di trascinamento e un metodo di callback per un oggetto View. In questo caso, il sistema chiama prima il listener. Il sistema non chiama il metodo di callback a meno che il listener non restituisca false.
La combinazione del metodo onDragEvent() e di View.OnDragListener è
analoga alla combinazione di
onTouchEvent()
e View.OnTouchListener
utilizzata con gli eventi touch.