Détecter les gestes courants

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser l'écran tactile et la saisie dans Compose.
<ph type="x-smartling-placeholder"></ph> Gestes →

Un geste tactile se produit lorsqu'un utilisateur place un ou plusieurs doigts sur la l'écran tactile et votre application interprète ce schéma de gestes comme un geste. Il y La détection des gestes se déroule en deux phases:

  1. Collecte des données d'événements tactiles...
  2. L'interprétation des données pour déterminer si elles répondent aux critères du gestes compatibles avec votre application.

Classes AndroidX

Les exemples présentés dans ce document utilisent la méthode GestureDetectorCompat et MotionEventCompat classes. Ces classes se trouvent dans le AndroidX bibliothèque. Dans la mesure du possible, utilisez les classes AndroidX pour assurer la compatibilité avec appareils antérieurs. MotionEventCompat ne remplace pas le paramètre MotionEvent . Il fournit plutôt des méthodes utilitaires statiques auxquelles vous transmettez MotionEvent pour recevoir l'action qui lui est associée .

Recueillir des données

Lorsqu'un utilisateur place un ou plusieurs doigts sur l'écran, le rappel onTouchEvent() sur la vue qui reçoit les événements tactiles. Pour chaque séquence de gestes comme la position, la pression, la taille et l'ajout d'une autre doigt, c'est-à-dire un geste, onTouchEvent() correspond à déclenché plusieurs fois.

Le geste commence lorsque l'utilisateur touche l'écran pour la première fois et continue suit la position du ou des doigts de l'utilisateur et se termine capturer l'événement final du dernier doigt de l'utilisateur quittant l'écran. Au cours de cette interaction, les MotionEvent ont été livrés à onTouchEvent() fournit les détails de chaque interaction. Votre application peut utiliser les données fournies par MotionEvent pour déterminer le geste qui l'intéresse se produit.

Enregistrer des événements tactiles pour une activité ou une vue

Pour intercepter les événements tactiles dans un Activity ou View, remplacez le rappel onTouchEvent().

L'extrait de code suivant utilise getAction() pour extraire l'action que l'utilisateur effectue à partir du paramètre event. Vous obtenez ainsi les données brutes dont vous avez besoin pour déterminer si un geste qui vous intéresse se produit.

Kotlin

class MainActivity : Activity() {
    ...
    // This example shows an Activity. You can use the same approach if you are 
    // subclassing a View.
    override fun onTouchEvent(event: MotionEvent): Boolean {
        return when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                Log.d(DEBUG_TAG, "Action was DOWN")
                true
            }
            MotionEvent.ACTION_MOVE -> {
                Log.d(DEBUG_TAG, "Action was MOVE")
                true
            }
            MotionEvent.ACTION_UP -> {
                Log.d(DEBUG_TAG, "Action was UP")
                true
            }
            MotionEvent.ACTION_CANCEL -> {
                Log.d(DEBUG_TAG, "Action was CANCEL")
                true
            }
            MotionEvent.ACTION_OUTSIDE -> {
                Log.d(DEBUG_TAG, "Movement occurred outside bounds of current screen element")
                true
            }
            else -> super.onTouchEvent(event)
        }
    }
}

Java

public class MainActivity extends Activity {
...
// This example shows an Activity. You can use the same approach if you are
// subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){
    switch(event.getAction()) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds of current screen element");
            return true;
        default :
            return super.onTouchEvent(event);
    }
}

Ce code génère des messages semblables à ce qui suit dans Logcat lorsque l'utilisateur appuie sur le bouton : touche et et faites glisser les éléments suivants:

GESTURES D   Action was DOWN
GESTURES D   Action was UP
GESTURES D   Action was MOVE

Pour les gestes personnalisés, vous pouvez ensuite traiter vous-même ces événements pour afin de déterminer s'ils représentent un geste que vous devez gérer. Toutefois, si votre utilise les gestes courants, tels que tapoter deux fois, appuyer et tenir, faire glisser, etc., vous pouvez exploiter GestureDetector . GestureDetector vous permet de détecter plus facilement les erreurs les gestes sans traiter vous-même les événements tactiles individuels. C'est décrites plus en détail dans la section Détecter les gestes.

Capturer des événements tactiles pour une vue unique

Au lieu de onTouchEvent(), vous pouvez joindre un View.OnTouchListener à n'importe quel View à l'aide de l'objet setOnTouchListener() . Cela permet d'écouter les événements tactiles sans sous-classer un View existante, comme illustré dans l'exemple suivant:

Kotlin

findViewById<View>(R.id.my_view).setOnTouchListener { v, event ->
    // Respond to touch events.
    true
}

Java

View myView = findViewById(R.id.my_view);
myView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        // Respond to touch events.
        return true;
    }
});

Veillez à créer un écouteur qui renvoie false pour ACTION_DOWN. Dans ce cas, l'écouteur n'est pas appelé pour l'appel ACTION_MOVE et Séquence ACTION_UP de événements. En effet, ACTION_DOWN est le point de départ les événements tactiles.

Si vous créez une vue personnalisée, vous pouvez remplacer onTouchEvent(), comme décrit précédemment.

Détecter les gestes

Android fournit la classe GestureDetector permettant de détecter les erreurs gestes. Parmi les gestes qu'il prend en charge, citons onDown(), onLongPress(), et onFling() Vous pouvez utiliser GestureDetector conjointement avec onTouchEvent() décrite précédemment.

Détecter tous les gestes compatibles

Lorsque vous instanciez un objet GestureDetectorCompat, l'une des est une classe qui implémente la classe GestureDetector.OnGestureListener de commande. GestureDetector.OnGestureListener avertit les utilisateurs lorsqu'un un événement tactile spécifique se produit. Pour permettre à votre GestureDetector pour recevoir les événements, remplacer la vue ou la méthode onTouchEvent() de l'activité et transmettre tous les événements observés. à l'instance du détecteur.

Dans l'extrait de code suivant, une valeur renvoyée par true méthodes on<TouchEvent> individuelles indique que l'événement tactile est géré. Une valeur renvoyée de false transmet les événements dans la pile d'affichage jusqu'à ce que l'appui soit effectué.

Si vous exécutez l'extrait suivant dans une application de test, vous pouvez avoir une idée de la façon dont sont déclenchées lorsque vous interagissez avec l'écran tactile. le contenu de MotionEvent concerne chaque événement tactile. Vous voyez alors la quantité de données générées pour des interactions simples.

Kotlin

private const val DEBUG_TAG = "Gestures"

class MainActivity :
        Activity(),
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener {

    private lateinit var mDetector: GestureDetectorCompat

    // Called when the activity is first created.
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener.
        mDetector = GestureDetectorCompat(this, this)
        // Set the gesture detector as the double-tap
        // listener.
        mDetector.setOnDoubleTapListener(this)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (mDetector.onTouchEvent(event)) {
            true
        } else {
            super.onTouchEvent(event)
        }
    }

    override fun onDown(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDown: $event")
        return true
    }

    override fun onFling(
            event1: MotionEvent,
            event2: MotionEvent,
            velocityX: Float,
            velocityY: Float
    ): Boolean {
        Log.d(DEBUG_TAG, "onFling: $event1 $event2")
        return true
    }

    override fun onLongPress(event: MotionEvent) {
        Log.d(DEBUG_TAG, "onLongPress: $event")
    }

    override fun onScroll(
            event1: MotionEvent,
            event2: MotionEvent,
            distanceX: Float,
            distanceY: Float
    ): Boolean {
        Log.d(DEBUG_TAG, "onScroll: $event1 $event2")
        return true
    }

    override fun onShowPress(event: MotionEvent) {
        Log.d(DEBUG_TAG, "onShowPress: $event")
    }

    override fun onSingleTapUp(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onSingleTapUp: $event")
        return true
    }

    override fun onDoubleTap(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDoubleTap: $event")
        return true
    }

    override fun onDoubleTapEvent(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: $event")
        return true
    }

    override fun onSingleTapConfirmed(event: MotionEvent): Boolean {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: $event")
        return true
    }

}

Java

public class MainActivity extends Activity implements
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{

    private static final String DEBUG_TAG = "Gestures";
    private GestureDetectorCompat mDetector;

    // Called when the activity is first created.
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener.
        mDetector = new GestureDetectorCompat(this,this);
        // Set the gesture detector as the double-tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        if (this.mDetector.onTouchEvent(event)) {
            return true;
        }
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) {
        Log.d(DEBUG_TAG,"onDown: " + event.toString());
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2,
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString());
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString());
    }

    @Override
    public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
            float distanceY) {
        Log.d(DEBUG_TAG, "onScroll: " + event1.toString() + event2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
        return true;
    }
}

Détecter un sous-ensemble de gestes compatibles

Si vous ne voulez traiter que quelques gestes, vous pouvez étendre GestureDetector.SimpleOnGestureListener au lieu d'implémenter GestureDetector.OnGestureListener de commande.

GestureDetector.SimpleOnGestureListener fournit une pour l'ensemble des on<TouchEvent> en renvoyant false pour chacune d'entre elles. Cela vous permet de remplacer uniquement les méthodes que vous qui vous intéressent. Par exemple, l'extrait de code suivant crée une classe qui étend GestureDetector.SimpleOnGestureListener et forçages onFling() et onDown().

Si vous utilisez GestureDetector.OnGestureListener ou GestureDetector.SimpleOnGestureListener, nous vous recommandons implémenter une méthode onDown() qui renvoie true. Ce car tous les gestes commencent par un message onDown(). Si vous renvoie false à partir de onDown(), comme suit : Par défaut, GestureDetector.SimpleOnGestureListener, le système suppose que vous voulez ignorer le reste du geste, et les autres méthodes de GestureDetector.OnGestureListener ne sont pas appelés. Cela peut entraîner des problèmes inattendus dans votre application. Retourner uniquement false à partir de onDown() si vous souhaitez vraiment ignorer un geste dans son intégralité.

Kotlin

private const val DEBUG_TAG = "Gestures"

class MainActivity : Activity() {

    private lateinit var mDetector: GestureDetectorCompat

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mDetector = GestureDetectorCompat(this, MyGestureListener())
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        mDetector.onTouchEvent(event)
        return super.onTouchEvent(event)
    }

    private class MyGestureListener : GestureDetector.SimpleOnGestureListener() {

        override fun onDown(event: MotionEvent): Boolean {
            Log.d(DEBUG_TAG, "onDown: $event")
            return true
        }

        override fun onFling(
                event1: MotionEvent,
                event2: MotionEvent,
                velocityX: Float,
                velocityY: Float
        ): Boolean {
            Log.d(DEBUG_TAG, "onFling: $event1 $event2")
            return true
        }
    }
}

Java

public class MainActivity extends Activity {

    private GestureDetectorCompat mDetector;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent event){
        if (this.mDetector.onTouchEvent(event)) {
              return true;
        }
        return super.onTouchEvent(event);
    }

    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = "Gestures";

        @Override
        public boolean onDown(MotionEvent event) {
            Log.d(DEBUG_TAG,"onDown: " + event.toString());
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString() + event2.toString());
            return true;
        }
    }
}

Ressources supplémentaires