Les sections suivantes expliquent quelques concepts clés du processus de glisser-déposer.
Processus de glisser-déposer
Le processus de glisser-déposer comporte quatre étapes ou états: démarrage, poursuite, suppression et fin.
- Commencé
En réponse au geste de glissement d'un utilisateur, votre application appelle
startDragAndDrop()
pour indiquer au système de lancer une opération de glisser-déposer. Les arguments de la méthode fournissent les éléments suivants:- Données à déplacer.
- Un rappel pour dessiner l'ombre de glissement
- Métadonnées décrivant les données glissées
- Le système répond en rappelant votre application pour obtenir une ombre de glissement. Le système affiche ensuite l'ombre de glissement sur l'appareil.
- Ensuite, le système envoie un événement de déplacement avec le type d'action
ACTION_DRAG_STARTED
à l'écouteur d'événement de déplacement de tous les objetsView
de la mise en page actuelle. Pour continuer à recevoir des événements de déplacement, y compris un événement de dépôt possible, l'écouteur d'événements de déplacement doit renvoyertrue
. Cela enregistre l'écouteur auprès du système. Seuls les écouteurs enregistrés continuent de recevoir des événements de glisser-déposer. À ce stade, les écouteurs peuvent également modifier l'apparence de leur objetView
de cible de dépôt pour indiquer que la vue peut accepter un événement de dépôt. - Si l'écouteur d'événement de glisser-déposer renvoie
false
, il ne reçoit pas d'événements de glisser-déposer pour l'opération en cours tant que le système n'envoie pas d'événement de glisser-déposer avec le type d'actionACTION_DRAG_ENDED
. En renvoyantfalse
, l'écouteur indique au système qu'il n'est pas intéressé par l'opération de glisser-déposer et qu'il ne souhaite pas accepter les données glissées.
- Poursuite de l'opération…
- L'utilisateur continue de faire glisser l'élément. Lorsque l'ombre de l'objet déplacé intersecte la zone de délimitation d'une cible de dépôt, le système envoie un ou plusieurs événements de glissement à l'écouteur d'événements de glissement de la cible. L'écouteur peut modifier l'apparence de la cible de dépôt
View
en réponse à l'événement. Par exemple, si l'événement indique que l'ombre de glissement entre dans la zone de délimitation de la cible de dépôt (type d'actionACTION_DRAG_ENTERED
), l'écouteur peut réagir en mettant en surbrillanceView
. - Déplacé
- L'utilisateur relâche l'ombre de glissement dans le cadre de délimitation d'une cible de dépôt. Le système envoie à l'écouteur de la cible de dépôt un événement de glissement avec le type d'action
ACTION_DROP
. L'objet d'événement de glissement contient les données transmises au système dans l'appel àstartDragAndDrop()
qui lance l'opération. L'écouteur doit renvoyer la valeur booléennetrue
au système si l'écouteur traite correctement les données abandonnées. : Cette étape ne se produit que si l'utilisateur place l'ombre de glissement dans la zone de délimitation d'unView
dont l'écouteur est enregistré pour recevoir des événements de glissement (une cible de dépôt). Si l'utilisateur relâche l'ombre de glissement dans toute autre situation, aucun événement de glissementACTION_DROP
n'est envoyé. - Terminé
Une fois que l'utilisateur a relâché l'ombre de glissement et que le système a envoyé
un événement de glisser-déposer avec le type d'action
ACTION_DROP
. Si nécessaire, le système envoie un événement de glisser-déposer avec le type d'actionACTION_DRAG_ENDED
pour indiquer que l'opération de glisser-déposer est terminée. Cela se produit quel que soit l'endroit où l'utilisateur relâche l'ombre de glissement. L'événement est envoyé à tous les écouteurs enregistrés pour recevoir des événements de glisser-déposer, même si l'écouteur reçoit également l'événementACTION_DROP
.
Chacune de ces étapes est décrite plus en détail dans la section Une opération de glisser-déposer.
Événements de déplacement
Le système envoie un événement de déplacement sous la forme d'un objet DragEvent
, qui contient un type d'action qui décrit ce qui se passe dans le processus de glisser-déposer. Selon le type d'action, l'objet peut également contenir d'autres données.
Les écouteurs d'événements de déplacement reçoivent l'objet DragEvent
. Pour obtenir le type d'action, les écouteurs appellent DragEvent.getAction()
.
La classe DragEvent
définit six valeurs possibles, décrites dans le tableau 1:
Tableau 1. Types d'actions DragEvent
Type d'action | Signification |
---|---|
ACTION_DRAG_STARTED |
L'application appelle startDragAndDrop() et obtient une ombre de glissement. Si l'écouteur souhaite continuer à recevoir des événements de glisser-déposer pour cette opération, il doit renvoyer la valeur booléenne true au système.
|
ACTION_DRAG_ENTERED |
L'ombre de glissement entre dans la zone de délimitation de l'View de l'écouteur d'événements de glissement. Il s'agit du premier type d'action d'événement que l'écouteur reçoit lorsque l'ombre de glissement entre dans la zone de délimitation.
|
ACTION_DRAG_LOCATION |
Après un événement ACTION_DRAG_ENTERED , l'ombre de glissement se trouve toujours dans la zone de délimitation de l'View de l'écouteur d'événement de glissement.
|
ACTION_DRAG_EXITED |
Après un événement ACTION_DRAG_ENTERED et au moins un événement ACTION_DRAG_LOCATION , l'ombre de glissement se déplace en dehors de la zone de délimitation de l'View de l'écouteur d'événement de glissement.
|
ACTION_DROP |
L'ombre de glissement se libère sur l'View de l'écouteur d'événements de glissement. Ce type d'action n'est envoyé à l'écouteur d'un objet View que si l'écouteur renvoie la valeur booléenne true en réponse à l'événement de glisser-déposer ACTION_DRAG_STARTED . Ce type d'action n'est pas envoyé si l'utilisateur relâche l'ombre de glissement sur un View dont l'écouteur n'est pas enregistré ou s'il relâche l'ombre de glissement sur un élément qui ne fait pas partie de la mise en page actuelle.
L'écouteur renvoie la valeur booléenne |
ACTION_DRAG_ENDED |
Le système met fin à l'opération de glisser-déposer. Ce type d'action n'est pas nécessairement précédé d'un événement ACTION_DROP . Si le système envoie un ACTION_DROP , la réception du type d'action ACTION_DRAG_ENDED n'implique pas que la suppression a réussi. L'écouteur doit appeler getResult() , comme indiqué dans le tableau 2, pour obtenir la valeur renvoyée en réponse à ACTION_DROP . Si un événement ACTION_DROP n'est pas envoyé, getResult() renvoie false .
|
L'objet DragEvent
contient également les données et les métadonnées que votre application fournit au système lors de l'appel de startDragAndDrop()
. Certaines données ne sont valides que pour certains types d'actions, comme indiqué dans le tableau 2. Pour en savoir plus sur les événements et les données associées, consultez la section Une opération de glisser-déposer.
Tableau 2. Données DragEvent valides par type d'action
Valeur getAction() |
Valeur getClipDescription() |
Valeur getLocalState() |
Valeur getX() |
Valeur getY() |
Valeur getClipData() |
Valeur getResult() |
---|---|---|---|---|---|---|
ACTION_DRAG_STARTED |
✓ | ✓ | ||||
ACTION_DRAG_ENTERED |
✓ | ✓ | ||||
ACTION_DRAG_LOCATION |
✓ | ✓ | ✓ | ✓ | ||
ACTION_DRAG_EXITED |
✓ | ✓ | ||||
ACTION_DROP |
✓ | ✓ | ✓ | ✓ | ✓ | |
ACTION_DRAG_ENDED |
✓ | ✓ |
Les méthodes DragEvent
getAction()
, describeContents()
, writeToParcel()
et toString()
renvoient toujours des données valides.
Si une méthode ne contient pas de données valides pour un type d'action particulier, elle renvoie null
ou 0, en fonction de son type de résultat.
Ombre de l'objet déplacé
Lors d'une opération de glisser-déposer, le système affiche une image que l'utilisateur fait glisser. Pour le déplacement de données, cette image représente les données en cours de glisser-déposer. Pour d'autres opérations, l'image représente un aspect de l'opération de glisser-déposer.
Cette image est appelée ombre de glissement. Vous le créez avec les méthodes que vous déclarez pour un objet View.DragShadowBuilder
. Vous transmettez le générateur au système lorsque vous démarrez une opération de glisser-déposer à l'aide de startDragAndDrop()
. Dans sa réponse à startDragAndDrop()
, le système appelle les méthodes de rappel que vous définissez dans View.DragShadowBuilder
pour obtenir une ombre de glissement.
La classe View.DragShadowBuilder
comporte deux constructeurs:
View.DragShadowBuilder(View)
Ce constructeur accepte tous les objets
View
de votre application. Le constructeur stocke l'objetView
dans l'objetView.DragShadowBuilder
afin que les rappels puissent y accéder pour créer l'ombre de glissement. La vue ne doit pas nécessairement être uneView
que l'utilisateur sélectionne pour lancer l'opération de glisser-déposer.Si vous utilisez ce constructeur, vous n'avez pas besoin d'étendre
View.DragShadowBuilder
ni d'ignorer ses méthodes. Par défaut, vous obtenez une ombre de glissement qui a la même apparence que l'View
que vous transmettez en tant qu'argument, centrée sous l'emplacement où l'utilisateur appuie sur l'écran.View.DragShadowBuilder()
Si vous utilisez ce constructeur, aucun objet
View
n'est disponible dans l'objetView.DragShadowBuilder
. Le champ est défini surnull
. Vous devez étendreView.DragShadowBuilder
et remplacer ses méthodes, sinon vous obtiendrez une ombre de glissement invisible. Le système ne génère aucune erreur.
La classe View.DragShadowBuilder
comporte deux méthodes qui créent ensemble l'ombre de glissement:
onProvideShadowMetrics()
Le système appelle cette méthode immédiatement après l'appel de
startDragAndDrop()
. Utilisez la méthode pour envoyer les dimensions et le point de contact de l'ombre de glissement au système. Cette méthode comporte deux paramètres:outShadowSize
:objetPoint
. La largeur de l'ombre de glissement est définie dansx
, et sa hauteur dansy
.outShadowTouchPoint
:objetPoint
. Le point de contact est l'emplacement dans l'ombre de glissement qui doit se trouver sous le doigt de l'utilisateur pendant le glissement. Sa position X est définie dansx
et sa position Y dansy
.onDrawShadow()
Immédiatement après l'appel de
onProvideShadowMetrics()
, le système appelleonDrawShadow()
pour créer l'ombre de glissement. La méthode comporte un seul argument, un objetCanvas
que le système construit à partir des paramètres que vous fournissez dansonProvideShadowMetrics()
. La méthode dessine l'ombre de glissement sur leCanvas
fourni.
Pour améliorer les performances, réduisez la taille de l'ombre de glissement. Pour un seul élément, vous pouvez utiliser une icône. Pour une sélection de plusieurs éléments, vous pouvez utiliser des icônes dans une pile plutôt que des images complètes réparties sur l'écran.
Écouteurs d'événements et méthodes de rappel de glisser-déposer
Un View
reçoit des événements de glisser-déposer avec un écouteur d'événements de glisser-déposer qui implémente View.OnDragListener
ou avec la méthode de rappel onDragEvent()
de la vue. Lorsque le système appelle la méthode ou l'écouteur, il fournit un argument DragEvent
.
Dans la plupart des cas, il est préférable d'utiliser un écouteur plutôt que la méthode de rappel. Lorsque vous concevez des UI, vous ne sous-classez généralement pas les classes View
, mais l'utilisation de la méthode de rappel vous oblige à créer des sous-classes pour remplacer la méthode. En comparaison, vous pouvez implémenter une classe d'écouteur, puis l'utiliser avec plusieurs objets View
différents. Vous pouvez également l'implémenter en tant que classe intégrée anonyme ou expression lambda. Pour définir l'écouteur d'un objet View
, appelez setOnDragListener()
.
Vous pouvez également modifier l'implémentation par défaut de onDragEvent()
sans remplacer la méthode. Définissez un OnReceiveContentListener
sur une vue. Pour en savoir plus, consultez setOnReceiveContentListener()
.
La méthode onDragEvent()
effectue ensuite les opérations suivantes par défaut:
- Renvoie "true" en réponse à l'appel de
startDragAndDrop()
. Appele
performReceiveContent()
si les données de glisser-déposer sont déposées sur la vue. Les données sont transmises à la méthode en tant qu'objetContentInfo
. La méthode appelleOnReceiveContentListener
.Renvoie la valeur "true" si les données de glisser-déposer sont déposées sur la vue et que
OnReceiveContentListener
consomme l'un des contenus.
Définissez OnReceiveContentListener
pour gérer les données spécifiquement pour votre application. Pour assurer la rétrocompatibilité jusqu'au niveau d'API 24, utilisez la version Jetpack de OnReceiveContentListener
.
Vous pouvez avoir un écouteur d'événement de glissement et une méthode de rappel pour un objet View
, auquel cas le système appelle d'abord l'écouteur. Le système n'appelle pas la méthode de rappel que si l'écouteur renvoie false
.
La combinaison de la méthode onDragEvent()
et de View.OnDragListener
est semblable à la combinaison de onTouchEvent()
et de View.OnTouchListener
utilisée avec les événements tactiles.