Un geste multipoint consiste à appuyer sur l'écran avec plusieurs pointeurs (doigts) en même temps. Ce document explique comment détecter les gestes impliquant plusieurs pointeurs.
Suivre plusieurs pointeurs
Lorsque plusieurs pointeurs appuient sur l'écran en même temps, le système génère les événements tactiles suivants:
ACTION_DOWN
: envoyé lorsque le premier pointeur appuie sur l'écran. Le geste est alors déclenché. La les données de ce pointeur se trouvent toujours à l'index0
dans leMotionEvent
ACTION_POINTER_DOWN
: envoyé lorsque des pointeurs supplémentaires arrivent à l'écran après le premier. Vous pouvez obtenir l'index du pointeur qui vient de descendre en utilisantgetActionIndex()
ACTION_MOVE
: lorsqu'un changement se produit dans un geste, impliquant n'importe quel nombre ces pointeurs.ACTION_POINTER_UP
: envoyé lorsqu'un pointeur non principal apparaît. Vous pouvez obtenir l'index du pointeur qui vient de monter à l'aide degetActionIndex()
.ACTION_UP
: envoyé lorsque le dernier pointeur quitte l'écran.ACTION_CANCEL
: indique que l'ensemble du geste, y compris tous les pointeurs, est annulé.
Gestes de début et de fin
Un geste est une série d'événements commençant par un ACTION_DOWN
et se terminant par un ACTION_UP
ou
ACTION_CANCEL
. Il y a un geste actif à la fois. La
les actions BAS, DÉPLACER, MONTER et ANNULER s'appliquent à l'ensemble du geste. Par exemple, un
un événement avec ACTION_MOVE
peut indiquer un mouvement pour tous les pointeurs
à ce moment-là.
Garder une trace des pointeurs
Utiliser l'index et l'ID du pointeur pour effectuer le suivi des pointeurs individuels
dans une MotionEvent
.
- Index: une
MotionEvent
stocke un pointeur dans un tableau. L'index d'un pointeur correspond à sa position dans ce tableau. La plupart des méthodesMotionEvent
utilisent l'index de pointeur comme un paramètre plutôt que l'ID de pointeur. - ID: chaque pointeur possède également un mappage d'ID qui reste persistant entre les événements tactiles pour permettre le suivi d'un pointeur individuel ; tout au long du geste.
Les pointeurs individuels apparaissent dans un événement de mouvement dans un ordre indéterminé. Ainsi,
l'index d'un pointeur peut changer d'un événement à l'autre, mais l'identifiant du pointeur
d'un pointeur reste constant tant qu'il reste
actif. Utilisez les
getPointerId()
pour obtenir l'identifiant d'un pointeur afin de le suivre sur toutes les
les événements de mouvement
dans un geste. Ensuite, pour des événements de mouvement successifs, utilisez la
findPointerIndex()
pour obtenir l'index de pointeur pour un ID de pointeur donné dans cet événement de mouvement.
Exemple :
Kotlin
private var mActivePointerId: Int = 0 override fun onTouchEvent(event: MotionEvent): Boolean { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0) // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. val (x: Float, y: Float) = event.findPointerIndex(mActivePointerId).let { pointerIndex -> // Get the pointer's current position. event.getX(pointerIndex) to event.getY(pointerIndex) } ... }
Java
private int mActivePointerId; public boolean onTouchEvent(MotionEvent event) { ... // Get the pointer ID. mActivePointerId = event.getPointerId(0); // ... Many touch events later... // Use the pointer ID to find the index of the active pointer // and fetch its position. int pointerIndex = event.findPointerIndex(mActivePointerId); // Get the pointer's current position. float x = event.getX(pointerIndex); float y = event.getY(pointerIndex); ... }
Pour prendre en charge plusieurs pointeurs tactiles, vous pouvez mettre en cache tous les pointeurs actifs avec
leurs identifiants au niveau de leur ACTION_POINTER_DOWN
individuel ;
Heure de l'événement ACTION_DOWN
. Supprimez les pointeurs de votre cache sur
ses événements ACTION_POINTER_UP
et ACTION_UP
. Vous pourriez
trouver ces ID mis en cache utiles pour gérer
correctement les autres événements d'action. Pour
Par exemple, lors du traitement d'un événement ACTION_MOVE
, recherchez l'index
chaque ID de pointeur actif mis en cache, récupérez ses coordonnées à l'aide de la méthode
getX()
et
getY()
fonctions, puis comparez ces coordonnées à celles de votre compte
identifier les pointeurs qui ont été déplacés.
Utiliser la fonction getActionIndex()
avec
ACTION_POINTER_UP
et ACTION_POINTER_DOWN
événements
uniquement. N'utilisez pas cette fonction avec les événements ACTION_MOVE
, car cela
renvoie toujours 0
.
Récupérer MotionEvent
actions
Utilisez les
getActionMasked()
ou la version de compatibilité
MotionEventCompat.getActionMasked()
pour récupérer l'action d'un MotionEvent
. Contrairement à la précédente
getAction()
, getActionMasked()
est conçu pour fonctionner avec plusieurs
ces pointeurs. Elle renvoie l'action sans les index de pointeur. Pour les actions associées à
un index de pointeur valide, utilisez getActionIndex()
pour renvoyer l'index de
les pointeurs associés à l'action, comme indiqué dans l'extrait suivant:
Kotlin
val (xPos: Int, yPos: Int) = MotionEventCompat.getActionMasked(event).let { action -> Log.d(DEBUG_TAG, "The action is ${actionToString(action)}") // Get the index of the pointer associated with the action. MotionEventCompat.getActionIndex(event).let { index -> // The coordinates of the current screen contact, relative to // the responding View or Activity. MotionEventCompat.getX(event, index).toInt() to MotionEventCompat.getY(event, index).toInt() } } if (event.pointerCount > 1) { Log.d(DEBUG_TAG, "Multitouch event") } else { // Single touch event. Log.d(DEBUG_TAG, "Single touch event") } ... // Given an action int, returns a string description. fun actionToString(action: Int): String { return when (action) { MotionEvent.ACTION_DOWN -> "Down" MotionEvent.ACTION_MOVE -> "Move" MotionEvent.ACTION_POINTER_DOWN -> "Pointer Down" MotionEvent.ACTION_UP -> "Up" MotionEvent.ACTION_POINTER_UP -> "Pointer Up" MotionEvent.ACTION_OUTSIDE -> "Outside" MotionEvent.ACTION_CANCEL -> "Cancel" else -> "" } }
Java
int action = MotionEventCompat.getActionMasked(event); // Get the index of the pointer associated with the action. int index = MotionEventCompat.getActionIndex(event); int xPos = -1; int yPos = -1; Log.d(DEBUG_TAG,"The action is " + actionToString(action)); if (event.getPointerCount() > 1) { Log.d(DEBUG_TAG,"Multitouch event"); // The coordinates of the current screen contact, relative to // the responding View or Activity. xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } else { // Single touch event. Log.d(DEBUG_TAG,"Single touch event"); xPos = (int)MotionEventCompat.getX(event, index); yPos = (int)MotionEventCompat.getY(event, index); } ... // Given an action int, returns a string description public static String actionToString(int action) { switch (action) { case MotionEvent.ACTION_DOWN: return "Down"; case MotionEvent.ACTION_MOVE: return "Move"; case MotionEvent.ACTION_POINTER_DOWN: return "Pointer Down"; case MotionEvent.ACTION_UP: return "Up"; case MotionEvent.ACTION_POINTER_UP: return "Pointer Up"; case MotionEvent.ACTION_OUTSIDE: return "Outside"; case MotionEvent.ACTION_CANCEL: return "Cancel"; } return ""; }
Ressources supplémentaires
Pour en savoir plus sur les événements d'entrée, consultez les ressources suivantes : références:
- Présentation des événements d'entrée
- Capteurs présentation
- Créez un afficher des contenus
- Faire glisser et redimensionner