Refus de la paume de la main avec le stylet

Icône de note 5 étoiles

Un stylet peut être un outil incroyablement productif et créatif. Toutefois, lorsque les utilisateurs dessinent, écrivent ou interagissent avec une application à l'aide d'un stylet, ils touchent parfois l'écran avec la paume de leur main. L'événement tactile peut être signalé à votre application avant que le système ne le reconnaisse et l'ignore comme une pression involontaire de la paume de la main.

Bonnes pratiques

Votre application doit identifier les événements tactiles involontaires et les ignorer. Dans Jetpack Compose, vous pouvez accéder à l'MotionEvent Android sous-jacent à partir d'un PointerEvent. Vérifiez si ACTION_CANCEL est présent dans MotionEvent. Cela indique qu'un geste doit s'arrêter et qu'il peut être nécessaire de l'annuler. Sur Android 13 (niveau d'API 33) ou version ultérieure, recherchez l'indicateur FLAG_CANCELED sur les événements ACTION_CANCEL et ACTION_POINTER_UP, qui fournit un signal fort indiquant que l'événement tactile n'était pas intentionnel, comme une pression avec la paume de la main.

Ingrédients

  • Modifier.pointerInput() : modificateur Compose utilisé pour traiter l'entrée du pointeur.
  • PointerEvent : représente un événement de pointeur dans Compose, qui contient un ou plusieurs changements.
  • PointerEvent.motionEvent : propriété d'extension qui permet d'accéder à l'MotionEvent Android sous-jacent (nullable).
  • MotionEvent : représente les événements tactiles et de mouvement. Contient les informations nécessaires pour déterminer si un événement doit être ignoré.
  • ACTION_CANCEL : constante MotionEvent indiquant qu'un geste a été annulé. Le geste doit s'arrêter et peut nécessiter d'être annulé.
  • ACTION_POINTER_UP : constante MotionEvent indiquant qu'un autre pointeur que le premier a augmenté (c'est-à-dire qu'il a abandonné le contact avec l'écran de l'appareil).
  • FLAG_CANCELED : constante MotionEvent indiquant que le pointeur a provoqué un événement tactile non intentionnel. Ajouté aux événements ACTION_POINTER_UP et ACTION_CANCEL sur Android 13 (niveau d'API 33) ou version ultérieure.

Étapes

Examinez les objets MotionEvent envoyés à votre application. Utilisez les API MotionEvent pour déterminer les caractéristiques des événements :

  • Événements à pointeur unique : recherchez ACTION_CANCEL, qui indique que le geste doit s'arrêter. Sur Android 13 et versions ultérieures, recherchez également FLAG_CANCELED pour confirmer que l'appui était involontaire.
  • Événements à pointeurs multiples : sur Android 13 et versions ultérieures, recherchez ACTION_POINTER_UP et FLAG_CANCELED pour identifier les touches non intentionnelles.

Répondez à ces événements en arrêtant le geste et en annulant toute modification temporaire.

1. Acquérir des objets d'événement de mouvement

Utilisez Modifier.pointerInput pour traiter l'entrée du pointeur sur un composable. Dans le champ d'entrée du pointeur, utilisez awaitPointerEventScope et awaitPointerEvent pour recevoir des événements, et récupérez le MotionEvent Android sous-jacent à l'aide de la propriété motionEvent :

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent
                        if (motionEvent != null) {
                            // Process motion event.
                        }
                    }
                }
            }
    )

2. Déterminer l'action et les indicateurs d'événement

Recherchez ACTION_CANCEL dans MotionEvent, qui indique un événement à pointeur unique à tous les niveaux d'API. Sur Android 13 ou version ultérieure, vérifiez ACTION_POINTER_UP pour FLAG_CANCELED :

import androidx.compose.ui.input.pointer.pointerInput
    Box(
        modifier = Modifier
            .fillMaxSize()
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    while (true) {
                        val event = awaitPointerEvent()
                        val motionEvent = event.motionEvent ?: continue

                        when (motionEvent.actionMasked) {
                            MotionEvent.ACTION_CANCEL -> {
                                // Process canceled single-pointer motion event for all SDK versions.
                            }
                            MotionEvent.ACTION_POINTER_UP -> {
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                                    (motionEvent.flags and MotionEvent.FLAG_CANCELED) == MotionEvent.FLAG_CANCELED
                                ) {
                                    // Process canceled multi-pointer motion event for Android 13 and higher.
                                }
                            }
                        }
                    }
                }
            }
    )

3. Annuler le geste

Après avoir identifié une pression de la paume de la main, vous pouvez annuler les effets à l'écran du geste.

Votre application doit conserver un historique des actions de l'utilisateur pour que les entrées involontaires (comme les pressions avec la paume de la main) puissent être annulées. Pour voir un exemple, consultez Implémenter une application de dessin de base dans l'atelier de programmation Améliorer la prise en charge des stylets dans une application Android.

Résultats

Votre application peut désormais identifier et refuser les gestes de la paume de la main pour les événements à plusieurs pointeurs sur Android 13 ou version ultérieure, et pour les événements à pointeur unique à tous les niveaux d'API.

Ressources supplémentaires

Pour en savoir plus, consultez les ressources suivantes :