Le seguenti sezioni spiegano alcuni concetti chiave della procedura di trascinamento.
Procedura di trascinamento
La procedura di trascinamento prevede quattro passaggi o stati: avviato, continuo, eliminato e terminato.
- Avviato
In risposta al gesto di trascinamento di un utente, l'applicazione chiama
startDragAndDrop()
per indicare al sistema di avviare un'operazione di trascinamento. Gli argomenti del metodo offrono quanto segue:- I dati da trascinare.
- Un callback per disegnare l'ombra trascinata
- Metadati che descrivono i dati trascinati
- Il sistema risponde richiamando l'applicazione per ottenere un'ombra a trascinamento. Il sistema visualizza l'ombra trascinata sul dispositivo.
- Successivamente, il sistema invia un evento di trascinamento con tipo di azione
ACTION_DRAG_STARTED
all'ascoltatore di eventi di trascinamento di tutti iView
oggetti nel layout corrente. Per continuare a ricevere eventi di trascinamento, incluso un possibile evento di trascinamento, il listener di eventi di trascinamento deve restituiretrue
. Questo registra il listener nel sistema. Solo i listener registrati continuano a ricevere eventi di trascinamento. A questo punto, i listener possono anche modificare l'aspetto dell'oggettoView
della destinazione di rilascio per indicare 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
. Se restituiscifalse
, il listener comunica al sistema che non è interessato all'operazione di trascinamento e non vuole accettare i dati trascinati.
- Avanzamento
- L'utente continua a trascinare. Quando l'ombra di trascinamento interseca il riquadro di selezione di una destinazione, il sistema invia uno o più eventi di trascinamento al listener di eventi di trascinamento della destinazione. Il listener potrebbe modificare l'aspetto della destinazione di rilascio
View
in risposta all'evento. Ad esempio, se l'evento indica che l'ombra di trascinamento entra nel riquadro di delimitazione della destinazione del rilascio (tipo di azioneACTION_DRAG_ENTERED
), il listener può reagire evidenziandoView
. - Interrotto
- L'utente rilascia l'ombra di trascinamento all'interno del riquadro di delimitazione di una destinazione. Il sistema invia al listener della destinazione di rilascio un evento di trascinamento con il tipo di azione
ACTION_DROP
. L'oggetto evento di trascinamento contiene i dati passati al sistema nella chiamata astartDragAndDrop()
che avvia l'operazione. Se il listener elabora correttamente i dati eliminati dovrebbe restituire il valore booleanotrue
nel sistema. : questo passaggio si verifica solo se l'utente rilascia l'ombra di trascinamento all'interno del riquadro di delimitazione di unView
il 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
. - Terminato
Dopo che l'utente ha rilasciato l'ombra trascinata e dopo che il sistema ha inviato
un evento di trascinamento con tipo di azione
ACTION_DROP
. Se necessario, il sistema invia un evento di trascinamento con il tipo di azioneACTION_DRAG_ENDED
per indicare che l'operazione di trascinamento è terminata. Ciò avviene indipendentemente da dove 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
.
Ciascuno di questi passaggi è descritto più dettagliatamente nella sezione Un'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,
gli ascoltatori chiamano
DragEvent.getAction()
.
Esistono sei possibili valori definiti da costanti nella classe DragEvent
, descritti nella tabella 1:
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 di evento che il listener riceve quando l'ombra di trascinamento entra nel riquadro di delimitazione.
|
ACTION_DRAG_LOCATION |
Dopo un evento ACTION_DRAG_ENTERED , l'ombra di trascinamento si trova ancora all'interno del riquadro di delimitazione dell'View del listener di eventi di trascinamento.
|
ACTION_DRAG_EXITED |
Dopo un ACTION_DRAG_ENTERED e almeno un
ACTION_DRAG_LOCATION evento, l'ombra di trascinamento si sposta
fuori dal riquadro di selezione del listener
View del listener di eventi di trascinamento.
|
ACTION_DROP |
L'ombra di trascinamento viene rilasciata sul valore View del listener di eventi di trascinamento. Questo tipo di azione viene inviato al listener di un oggetto View solo se il listener restituisce il valore booleano true in risposta all'evento di trascinamento ACTION_DRAG_STARTED . 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 l'elemento 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 messaggio ACTION_DROP , la ricezione del
tipo di azione ACTION_DRAG_ENDED non implica che il
rilascio sia riuscito. Il listener deve chiamare
getResult() ,
come mostrato nella tabella 2, per ottenere il valore
restituito in risposta a ACTION_DROP . Se un
evento ACTION_DROP non viene inviato, 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 azioni, come riepilogato nella tabella 2. Per ulteriori informazioni sugli eventi e sui relativi dati, consulta la sezione Un'operazione di trascinamento.
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.
Trascina ombra
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 alcuni aspetti dell'operazione di trascinamento.
L'immagine è chiamata ombra di trascinamento. Puoi crearlo con i metodi dichiarati per un oggetto View.DragShadowBuilder
. 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 che hai definito in View.DragShadowBuilder
per ottenere un'ombreggiatura a trascinamento.
La classe View.DragShadowBuilder
ha due costruttori:
View.DragShadowBuilder(View)
Questo costruttore accetta tutti gli oggetti
View
dell'applicazione. Il costruttore archivia l'oggettoView
nell'oggettoView.DragShadowBuilder
, in modo che i callback possano accedervi per creare l'ombra di trascinamento. La vista non deve essere necessariamente unView
selezionato dall'utente per avviare l'operazione di trascinamento.Se utilizzi questo costruttore, non è necessario estendere
View.DragShadowBuilder
o sovrascrivere i relativi metodi. Per impostazione predefinita, viene visualizzata un'ombra a trascinamento che ha lo stesso aspetto delView
trasmesso come argomento, centrato nella posizione in cui l'utente tocca lo schermo.View.DragShadowBuilder()
Se utilizzi questo costruttore, nell'oggetto
View.DragShadowBuilder
non sarà disponibile nessun oggettoView
. Il campo è impostato sunull
. Devi estendereView.DragShadowBuilder
e sovrascrivere i relativi metodi, altrimenti otterrai un'ombreggiatura invisibile di trascinamento. 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 subito 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
: un oggettoPoint
. La larghezza dell'ombra di trascinamento va inx
e l'altezza deve essere iny
.outShadowTouchPoint
: un oggettoPoint
. Il punto di contatto è la posizione all'interno dell'ombra del trascinamento che deve trovarsi sotto il dito dell'utente durante il trascinamento. La sua posizione X va inx
e la sua posizione Y va iny
.onDrawShadow()
Subito dopo la chiamata a
onProvideShadowMetrics()
, il sistema chiamaonDrawShadow()
per creare l'ombra di trascinamento. Il metodo ha un singolo argomento, un oggettoCanvas
che il sistema crea dai parametri che fornisci inonProvideShadowMetrics()
. Il metodo disegna l'ombra di trascinamento sull'elementoCanvas
fornito.
Per migliorare le prestazioni, riduci le dimensioni dell'ombra di trascinamento. Per un singolo elemento, è consigliabile utilizzare un'icona. Per una selezione di più elementi, potresti voler utilizzare icone in pila anziché immagini complete sparse 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 vista. Quando il sistema chiama il metodo o il listener, fornisce un argomento DragEvent
.
Nella maggior parte dei casi, è preferibile utilizzare un listener che utilizzare il metodo di callback. Quando progetti UI, di solito non sottoclassi le classi View
, ma se usi il metodo di callback, devi creare delle sottoclassi per sostituire il metodo. A confronto, puoi implementare una classe listener e quindi utilizzarla con più oggetti View
diversi. Puoi implementarla anche come classe
in linea anonima o espressione lambda. Per impostare il listener per un oggetto View
, chiama
setOnDragListener()
.
In alternativa, puoi modificare l'implementazione predefinita di onDragEvent()
senza eseguire l'override del metodo. Impostare un elemento OnReceiveContentListener
su una vista. Per ulteriori dettagli, consulta setOnReceiveContentListener()
.
Per impostazione predefinita, il metodo onDragEvent()
effettua le seguenti operazioni:
- Restituisce true in risposta alla chiamata a
startDragAndDrop()
. Chiamate
performReceiveContent()
se i dati relativi al trascinamento vengono rilasciati nella vista. I dati vengono passati al metodo come oggettoContentInfo
. Il metodo richiamaOnReceiveContentListener
.Restituisce true se i dati di trascinamento vengono eliminati nella vista e
OnReceiveContentListener
consuma qualsiasi contenuto.
Definisci il OnReceiveContentListener
per gestire i dati specificamente per la tua
app. Per la compatibilità con le versioni precedenti al livello API 24, utilizza la versione Jetpack di
OnReceiveContentListener
.
Per un oggetto View
puoi avere un listener di eventi di trascinamento e un metodo di callback, nel qual 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
utilizzati con gli eventi tocco.