Suivre les mouvements tactiles et du curseur

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 →

Cette leçon explique comment suivre les mouvements lors des événements tactiles.

Une nouvelle onTouchEvent() est déclenché par une ACTION_MOVE événement chaque fois que la position, la pression ou la taille du contact tactile change. En tant que décrites dans la section Détecter les gestes courants, tous ces événements sont enregistrés Paramètre MotionEvent de onTouchEvent()

Comme le toucher n'est pas toujours la forme d'interaction la plus précise, La détection des événements tactiles repose souvent davantage sur le mouvement que sur un simple contact. Pour aider les applications à distinguer les gestes basés sur les mouvements (un balayage, par exemple) et des gestes sans mouvement (comme un simple tapotement), Android inclut la notion de pente tactile. La pente tactile désigne la distance, en pixels, où un utilisateur touche errer avant que le geste ne soit interprété comme un geste basé sur le mouvement. Pour plus informations sur ce thème, consultez l'article Gérer les événements tactiles dans un ViewGroup

Il existe plusieurs façons de suivre les mouvements dans un geste, en fonction de aux besoins de votre application. Voici des exemples:

  • Les positions de début et de fin d'un pointeur, par exemple le déplacement d'un élément à l'écran d'un point A à un point B.
  • la direction dans laquelle se déplace le pointeur, telle que déterminée par les coordonnées X et Y ; coordonnées.
  • Historique. Vous pouvez connaître la taille de l'historique d'un geste en appelant la méthode MotionEvent méthode getHistorySize() Vous pouvez ensuite obtenir la position, la taille, la durée et la pression de chacun des les événements historiques à l'aide de l'événement de mouvement getHistorical<Value> méthodes. L'historique est utile pour afficher une trace du doigt de l'utilisateur, par exemple comme pour le dessin tactile. Pour en savoir plus, consultez la documentation de référence sur MotionEvent.
  • Vitesse du pointeur lorsqu'il se déplace sur l'écran tactile.

Consultez les ressources associées suivantes :

Suivre la vitesse

Vous pouvez effectuer un geste basé sur les mouvements en fonction de la distance ou de la direction. le pointeur se déplace. Cependant, la vitesse est souvent un facteur déterminant dans le suivi les caractéristiques d'un geste ou de décider si le geste s'est produit. Pour calcul de la vitesse, Android fournit VelocityTracker. VelocityTracker vous aide à suivre la vitesse des événements tactiles. C'est utile pour les gestes dont la vitesse fait partie des critères du geste, comme un geste vif.

Voici un exemple illustrant l'objectif des méthodes du API VelocityTracker:

Kotlin

private const val DEBUG_TAG = "Velocity"

class MainActivity : Activity() {
    private var mVelocityTracker: VelocityTracker? = null

    override fun onTouchEvent(event: MotionEvent): Boolean {

        when (event.actionMasked) {
            MotionEvent.ACTION_DOWN -> {
                // Reset the velocity tracker back to its initial state.
                mVelocityTracker?.clear()
                // If necessary, retrieve a new VelocityTracker object to watch
                // the velocity of a motion.
                mVelocityTracker = mVelocityTracker ?: VelocityTracker.obtain()
                // Add a user's movement to the tracker.
                mVelocityTracker?.addMovement(event)
            }
            MotionEvent.ACTION_MOVE -> {
                mVelocityTracker?.apply {
                    val pointerId: Int = event.getPointerId(event.actionIndex)
                    addMovement(event)
                    // When you want to determine the velocity, call
                    // computeCurrentVelocity(). Then, call getXVelocity() and
                    // getYVelocity() to retrieve the velocity for each pointer
                    // ID.
                    computeCurrentVelocity(1000)
                    // Log velocity of pixels per second. It's best practice to
                    // use VelocityTrackerCompat where possible.
                    Log.d("", "X velocity: ${getXVelocity(pointerId)}")
                    Log.d("", "Y velocity: ${getYVelocity(pointerId)}")
                }
            }
            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                // Return a VelocityTracker object back to be re-used by others.
                mVelocityTracker?.recycle()
                mVelocityTracker = null
            }
        }
        return true
    }
}

Java

public class MainActivity extends Activity {
    private static final String DEBUG_TAG = "Velocity";
        ...
    private VelocityTracker mVelocityTracker = null;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int index = event.getActionIndex();
        int action = event.getActionMasked();
        int pointerId = event.getPointerId(index);

        switch(action) {
            case MotionEvent.ACTION_DOWN:
                if(mVelocityTracker == null) {
                    // Retrieve a new VelocityTracker object to watch the
                    // velocity of a motion.
                    mVelocityTracker = VelocityTracker.obtain();
                }
                else {
                    // Reset the velocity tracker back to its initial state.
                    mVelocityTracker.clear();
                }
                // Add a user's movement to the tracker.
                mVelocityTracker.addMovement(event);
                break;
            case MotionEvent.ACTION_MOVE:
                mVelocityTracker.addMovement(event);
                // When you want to determine the velocity, call
                // computeCurrentVelocity(). Then call getXVelocity() and
                // getYVelocity() to retrieve the velocity for each pointer ID.
                mVelocityTracker.computeCurrentVelocity(1000);
                // Log velocity of pixels per second. It's best practice to use
                // VelocityTrackerCompat where possible.
                Log.d("", "X velocity: " + mVelocityTracker.getXVelocity(pointerId));
                Log.d("", "Y velocity: " + mVelocityTracker.getYVelocity(pointerId));
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                // Return a VelocityTracker object back to be re-used by others.
                mVelocityTracker.recycle();
                break;
        }
        return true;
    }
}

Utiliser la capture du pointeur

Certaines applications, comme les jeux, le bureau à distance et les clients de virtualisation, de contrôler le pointeur de la souris. La capture par pointeur est une fonctionnalité disponible sur Android 8.0 (niveau d'API 26) ou version ultérieure, qui permet de contrôler Diffuser tous les événements de souris dans une vue sélectionnée de votre application

Demander la capture du pointeur

Une vue de votre application ne peut demander la capture du pointeur que lorsque la hiérarchie des vues qui où elle est ciblée. Pour cette raison, demandez la capture du pointeur lorsqu'un une action spécifique de l'utilisateur sur la vue, par exemple lors d'une onClick() ou dans l'événement onWindowFocusChanged() gestionnaire d'événements de votre activité.

Pour demander la capture du pointeur, appelez la méthode requestPointerCapture() sur la vue. L'exemple de code suivant montre comment demander un pointeur lorsque l'utilisateur clique sur une vue:

Kotlin

fun onClick(view: View) {
    view.requestPointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.requestPointerCapture();
}

Une fois que la requête de capture du pointeur aboutit, Android appelle onPointerCaptureChange(true) Le système diffuse les événements de souris dans la vue sélectionnée de votre application tant que elle se trouve dans la même hiérarchie des vues que la vue qui a demandé la capture. Autre les applications ne reçoivent plus les événements de souris jusqu'à ce que la capture soit relâchée, y compris ACTION_OUTSIDE événements. Android diffuse les événements de pointeur provenant de sources autres que la souris, mais le pointeur de la souris n'est plus visible.

Gérer les événements de pointeur capturés

Lorsqu'une vue acquiert la capture du pointeur, Android transmet les événements de souris. La vue sélectionnée peut gérer les événements en effectuant l'une des opérations tâches suivantes:

L'exemple de code suivant montre comment implémenter onCapturedPointerEvent(MotionEvent):

Kotlin

override fun onCapturedPointerEvent(motionEvent: MotionEvent): Boolean {
    // Get the coordinates required by your app.
    val verticalOffset: Float = motionEvent.y
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    return true
}

Java

@Override
public boolean onCapturedPointerEvent(MotionEvent motionEvent) {
  // Get the coordinates required by your app.
  float verticalOffset = motionEvent.getY();
  // Use the coordinates to update your view and return true if the event is
  // successfully processed.
  return true;
}

L'exemple de code suivant montre comment enregistrer un OnCapturedPointerListener:

Kotlin

myView.setOnCapturedPointerListener { view, motionEvent ->
    // Get the coordinates required by your app.
    val horizontalOffset: Float = motionEvent.x
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    true
}

Java

myView.setOnCapturedPointerListener(new View.OnCapturedPointerListener() {
  @Override
  public boolean onCapturedPointer (View view, MotionEvent motionEvent) {
    // Get the coordinates required by your app.
    float horizontalOffset = motionEvent.getX();
    // Use the coordinates to update your view and return true if the event is
    // successfully processed.
    return true;
  }
});

Que vous utilisiez une vue personnalisée ou que vous enregistriez un écouteur, votre vue reçoit une MotionEvent avec les coordonnées du pointeur qui spécifient des mouvements relatifs comme X ou deltas Y, similaires aux coordonnées livrées par un trackball. Vous pouvez récupérer les coordonnées en utilisant getX() et getY()

Libérer la capture du pointeur

La vue de votre application peut libérer la capture du pointeur en appelant releasePointerCapture(), comme illustré dans l'exemple de code suivant:

Kotlin

override fun onClick(view: View) {
    view.releasePointerCapture()
}

Java

@Override
public void onClick(View view) {
    view.releasePointerCapture();
}

Le système peut retirer la capture de la vue sans que vous ayez explicitement en appelant releasePointerCapture(), généralement parce que la hiérarchie des vues contenant la vue qui demande une capture perd son focus.