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 : "Commencé", "Poursuite", "Supprimé" et "Terminé".
- Commencé
En réponse au geste de déplacement d'un utilisateur, votre application appelle
startDragAndDrop()pour indiquer au système de démarrer une opération de glisser-déposer. Les arguments de la méthode fournissent les éléments suivants :- Les données à faire glisser
- Un rappel pour dessiner l'ombre de l'objet déplacé
- Les métadonnées décrivant les données déplacées
- Le système répond en rappelant votre application pour obtenir une ombre de l'objet déplacé. Le système affiche ensuite l'ombre de l'objet déplacé 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énements de déplacement de tous les objetsViewde la mise en page actuelle. Pour continuer à recevoir des événements de déplacement, y compris un éventuel événement de suppression, 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 déplacement. À ce stade, les écouteurs peuvent également modifier l'apparence de leur objetViewcible de dépôt pour indiquer que la vue peut accepter un événement de suppression. - Si l'écouteur d'événements de déplacement renvoie
false, il ne reçoit pas d'événements de déplacement pour l'opération en cours tant que le système n'envoie pas d'événement de déplacement 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 déplacées.
- Poursuite
- L'utilisateur continue le déplacement. Lorsque l'ombre de l'objet déplacé croise le cadre de délimitation d'une cible de dépôt, le système envoie un ou plusieurs événements de déplacement à l'écouteur d'événements de déplacement de la cible. L'écouteur peut modifier l'apparence de la
Viewcible de dépôt en réponse à l'événement. Par exemple, si l'événement indique que l'ombre de l'objet déplacé entre dans le cadre de délimitation de la cible de dépôt (type d'actionACTION_DRAG_ENTERED), l'écouteur peut réagir en mettant en surbrillance laView. - Supprimé
- L'utilisateur relâche l'ombre de l'objet déplacé 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 déplacement avec action
type
ACTION_DROP. L'objet d'événement de déplacement contient les données transmises au système lors de l'appel àstartDragAndDrop()qui démarre l'opération. L'écouteur doit renvoyer la valeur booléennetrueau système s'il traite correctement les données supprimées. : Cette étape ne se produit que si l'utilisateur supprime l'ombre de l'objet déplacé dans le cadre de délimitation d'uneViewdont l'écouteur est enregistré pour recevoir des événements de déplacement (une cible de dépôt). Si l'utilisateur relâche l'ombre de l'objet déplacé dans une autre situation, aucun événement de déplacementACTION_DROPn'est envoyé. - Terminé
Une fois que l'utilisateur a relâché l'ombre de l'objet déplacé et que le système a envoyé
un événement de déplacement avec le type d'action
ACTION_DROP, si nécessaire, le système envoie un événement de déplacement avec le type d'actionACTION_DRAG_ENDEDpour 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 l'objet déplacé. L'événement est envoyé à chaque écouteur enregistré pour recevoir des événements de déplacement, 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 appelée 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 décrivant 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().
Il existe six valeurs possibles définies par des constantes dans la classe DragEvent, qui sont 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 l'objet déplacé. Si l'écouteur souhaite continuer à recevoir des événements de déplacement
pour cette opération, il doit renvoyer la valeur booléenne true au
système.
|
ACTION_DRAG_ENTERED |
L'ombre de l'objet déplacé entre dans le cadre de délimitation de la
View de l'écouteur d'événements de déplacement. Il s'agit du premier type d'action d'événement que l'écouteur
reçoit lorsque l'ombre de l'objet déplacé entre dans le cadre de délimitation.
|
ACTION_DRAG_LOCATION |
Après un
ACTION_DRAG_ENTERED événement, l'ombre de l'objet déplacé se trouve toujours
dans le cadre de délimitation de l'écouteur d'événements de déplacement
View.
|
ACTION_DRAG_EXITED |
Après un ACTION_DRAG_ENTERED et au moins un
ACTION_DRAG_LOCATION événement, l'ombre de l'objet déplacé se déplace
en dehors du cadre de délimitation de la
View de l'écouteur d'événements de déplacement.
|
ACTION_DROP |
L'ombre de l'objet déplacé est relâchée sur le
View de l'écouteur d'événements de déplacement. 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 déplacement
ACTION_DRAG_STARTED. Ce type d'action n'est
envoyé si l'utilisateur relâche l'ombre de l'objet déplacé sur un View
dont l'écouteur n'est pas enregistré ou si l'utilisateur relâche l'ombre de l'objet déplacé 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 ACTION_DROP événement. 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 aucun
ACTION_DROP événement n'est envoyé, alors
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 à 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 appelée Opération de glisser-déposer.
Tableau 2. Données DragEvent valides par type d'action
getAction()valeur |
getClipDescription()valeur |
getLocalState()valeur |
getX()valeur |
getY()valeur |
getClipData()valeur |
getResult()valeur |
|---|---|---|---|---|---|---|
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, selon 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 déplacées. Pour les autres opérations, l'image représente un aspect de l'opération de déplacement.
Cette image est appelée ombre de l'objet déplacé. Vous la créez avec des méthodes que vous déclarez pour
un
View.DragShadowBuilder
objet. Vous transmettez le compilateur au système lorsque vous démarrez une opération de glisser-déposer à l'aide de startDragAndDrop(). Dans le cadre de 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 l'objet déplacé.
La classe View.DragShadowBuilder comporte deux constructeurs :
View.DragShadowBuilder(View)Ce constructeur accepte n'importe quel objet
Viewde votre application. Le constructeur stocke l'objetViewdans l'objetView.DragShadowBuilder, afin que les rappels puissent y accéder pour construire l'ombre de l'objet déplacé. La vue ne doit pas nécessairement être uneViewque l'utilisateur sélectionne pour démarrer l'opération de déplacement.Si vous utilisez ce constructeur, vous n'avez pas besoin d'étendre
View.DragShadowBuilderni de remplacer ses méthodes. Par défaut, vous obtenez une ombre de l'objet déplacé qui a la même apparence que laViewque vous transmettez en tant qu'argument, centrée sous l'endroit où l'utilisateur touche l'écran.View.DragShadowBuilder()Si vous utilisez ce constructeur, aucun objet
Viewn'est disponible dans l'objetView.DragShadowBuilder. Le champ est défini surnull. Vous devez étendreView.DragShadowBuilderet remplacer ses méthodes, sinon vous obtenez une ombre de l'objet déplacé invisible. Le système ne génère pas d'erreur.
La classe View.DragShadowBuilder comporte deux méthodes qui créent ensemble l'ombre de l'objet déplacé :
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 l'objet déplacé au système. La méthode comporte deux paramètres :outShadowSize: unPointobjet. La largeur de l'ombre de l'objet déplacé est placée dansx, et sa hauteur dansy.outShadowTouchPoint: objetPoint. Le point de contact est l'emplacement de l'ombre de l'objet déplacé qui doit se trouver sous le doigt de l'utilisateur pendant le déplacement. Sa position X est placée dansxet sa position Y dansy.onDrawShadow()Immédiatement après l'appel à
onProvideShadowMetrics(), le système appelleonDrawShadow()pour créer l'ombre de l'objet déplacé. La méthode comporte un seul argument, unCanvasobjet que le système construit à partir des paramètres que vous fournissez dansonProvideShadowMetrics(). La méthode dessine l'ombre de l'objet déplacé sur leCanvasfourni.
Pour améliorer les performances, réduisez la taille de l'ombre de l'objet déplacé. 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 de déplacement et méthodes de rappel
A View reçoit des événements de déplacement avec un écouteur d'événements de déplacement 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
DragEvent argument.
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 interfaces utilisateur, 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 la valeur "true" en réponse à l'appel à
startDragAndDrop(). Appelle
performReceiveContent()si les données de glisser-déposer sont supprimées dans la vue. Les données sont transmises à la méthode en tant qu'ContentInfoobjet. La méthode appelle leOnReceiveContentListener.Renvoie la valeur "true" si les données de glisser-déposer sont supprimées dans la vue et que le
OnReceiveContentListenerconsomme une partie du contenu.
Définissez le 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énements de déplacement et une méthode de rappel pour un objet View. Dans ce cas, le système appelle d'abord l'écouteur. Le système n'appelle pas la méthode de rappel, sauf si l'écouteur renvoie false.
La combinaison de la méthode onDragEvent() et de View.OnDragListener est
analogue à la combinaison de
onTouchEvent()
et View.OnTouchListener
utilisée avec les événements tactiles.