Utiliser les mouvements du poignet sur Wear

Restez organisé à l'aide des collections Enregistrez et classez les contenus selon vos préférences.

Les mouvements du poignet vous permettent d'interagir d'une seule main avec votre application lorsqu'un écran tactile ne le permet pas.

Par exemple, un utilisateur peut faire défiler les notifications avec une main tout en tenant un verre d'eau dans l'autre. Voici quelques exemples d'utilisation des mouvements du poignet :

  • Dans une application de jogging, vous pouvez parcourir les écrans verticaux qui indiquent le nombre de pas effectués, le temps écoulé et le rythme actuel.
  • À l'aéroport, avec les bagages dans une main, vous pouvez faire défiler les informations sur les vols et les portes d'embarquement avec l'autre main.
  • Vous pouvez parcourir des articles d'actualités.

Pour vérifier ce que font les mouvements du poignet sur votre montre, sélectionnez Paramètres > Gestes > Mouvements du poignet activés pour confirmer que cette fonctionnalité est activée. Suivez ensuite le tutoriel de la montre sur les gestes (Paramètres > Gestes > Lancer le tutoriel).

Les gestes suivants ne sont pas possibles dans les applications à partir de l'aide de Wear OS :

  • Secouer le poignet

Vous pouvez utiliser les mouvements du poignet de différentes manières :

Chaque mouvement du poignet est mappé à une constante int de la classe KeyEvent, comme indiqué dans le tableau suivant :

Geste KeyEvent Description
Tournez le poignet vers l'extérieur. KEYCODE_NAVIGATE_NEXT Ce code de clavier permet de passer à l'élément suivant.
Tournez le poignet vers l'intérieur. KEYCODE_NAVIGATE_PREVIOUS Ce code de clavier permet de passer à l'élément précédent.

Utiliser une mise en page incurvée pour permettre les mouvements du poignet

La classe WearableRecyclerView offre une mise en page incurvée pour les listes et accepte automatiquement les mouvements du poignet. Elle comporte des actions prédéfinies pour les mouvements du poignet lorsque la vue est ciblée. Pour en savoir plus sur l'utilisation de la classe WearableRecyclerView, consultez la section Créer des listes. Consultez également les bonnes pratiques.

Remarque : La classe WearableRecyclerView remplace une classe similaire obsolète de la bibliothèque Wearable Support.

Même si vous utilisez une propriété WearableRecyclerView, vous pouvez utiliser des constantes de la classe KeyEvent. Les actions prédéfinies peuvent être remplacées en sous-classant WearableRecyclerView et en implémentant de nouveau le rappel onKeyDown(). Vous pouvez désactiver entièrement ce comportement à l'aide de la méthode setEnableGestureNavigation(false). Consultez également Gérer les actions du clavier.

Utiliser des événements de touches directement

Pour déclencher de nouvelles actions en réponse à des événements gestuels, vous pouvez utiliser des événements de touches en dehors d'un élément WearableRecyclerView. Notez toutefois les points importants suivants :

  • Les événements gestuels sont reconnus lorsqu'un appareil est en mode actif.
  • Les événements gestuels sont diffusés de la même manière que tous les événements de touches.

Plus précisément, ces événements sont transmis à la première activité, à la vue ciblée par le clavier. Comme tout autre événement de touches, une classe liée à l'interaction utilisateur (telle qu'une vue ou une activité) qui implémente KeyEvent.Callback peut écouter les événements de touches associés aux mouvements du poignet. Le framework Android appelle la vue ou l'activité ciblée via les événements de touches. Pour les gestes, le rappel de la méthode onKeyDown() est appelé lorsque des gestes se produisent.

Par exemple, une application peut ignorer les actions prédéfinies dans une vue ou une activité (implémentant toutes deux KeyEvent.Callback) comme suit :

Kotlin

class GesturesActivity : Activity() {

    /* KeyEvent.Callback */
    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        return when (keyCode) {
            KeyEvent.KEYCODE_NAVIGATE_NEXT ->
                // Do something that advances a user View to the next item in an ordered list.
                moveToNextItem()
            KeyEvent.KEYCODE_NAVIGATE_PREVIOUS ->
                // Do something that advances a user View to the previous item in an ordered list.
                moveToPreviousItem()
            else -> {
                // If you did not handle it, let it be handled by the next possible element as deemed
                // by the Activity.
                super.onKeyDown(keyCode, event)
            }
        }
    }

    /** Shows the next item in the custom list.  */
    private fun moveToNextItem(): Boolean {
        …
        // Return true if handled successfully, otherwise return false.
        return false
    }

    /** Shows the previous item in the custom list.  */
    private fun moveToPreviousItem(): Boolean {
        …
        // Return true if handled successfully, otherwise return false.
        return false
    }
}

Java

public final class GesturesActivity extends Activity {

 @Override /* KeyEvent.Callback */
 public boolean onKeyDown(int keyCode, KeyEvent event) {
  switch (keyCode) {
   case KeyEvent.KEYCODE_NAVIGATE_NEXT:
    // Do something that advances a user View to the next item in an ordered list.
    return moveToNextItem();
   case KeyEvent.KEYCODE_NAVIGATE_PREVIOUS:
    // Do something that advances a user View to the previous item in an ordered list.
    return moveToPreviousItem();
  }
  // If you did not handle it, let it be handled by the next possible element as deemed by the Activity.
  return super.onKeyDown(keyCode, event);
 }

 /** Shows the next item in the custom list. */
 private boolean moveToNextItem() {
  boolean handled = false;
  …
  // Return true if handled successfully, otherwise return false.
  return handled;
 }

 /** Shows the previous item in the custom list. */
 private boolean moveToPreviousItem() {
  boolean handled = false;
  …
  // Return true if handled successfully, otherwise return false.
  return handled;
 }
}

Bonnes pratiques

  • Examinez les pages KeyEvent et KeyEvent.Callback concernant la diffusion des événements de touches pour la vue et l'activité.
  • Assurez-vous de la cohérence de l'accessibilité directionnelle :
    • Faites tourner le poignet vers l'extérieur pour passer à l'élément suivant et faites-le pivoter vers l'intérieur pour passer à l'élément précédent.
  • Effectuez une pression en parallèle pour un geste.
  • Fournissez des commentaires visuels.
  • N'utilisez pas de code de clavier pour implémenter une fonctionnalité qui serait contraire au reste du système. Par exemple, n'utilisez pas KEYCODE_NAVIGATE_NEXT pour annuler une action ou pour parcourir l'axe de gauche à droite avec des rotations du poignet.
  • N'interceptez pas les événements de touches au niveau d'éléments qui ne font pas partie de l'interface utilisateur, tels que les vues qui sont hors de l'écran ou partiellement couvertes. Cela est vrai pour tout autre événement de touche.
  • Ne réinterprétez pas les mouvements du poignet répétés dans un nouveau geste qui vous est propre. Cela pourrait être confondu avec le secouement du poignet.
  • Pour qu'une vue reçoive les événements de touches associés aux gestes, elle doit être ciblée. Consultez View::setFocusable(). Étant donné que les gestes sont traités comme des événements de touches, ils déclenchent une transition qui quitte le "mode tactile" et qui peut donc entraîner des actions inattendues. Par conséquent, comme les utilisateurs peuvent alterner entre l'écran tactile et les gestes, la méthode View::setFocusableInTouchmode() peut s'avérer nécessaire. Dans certains cas, il peut également être nécessaire d'utiliser setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS) pour que la vue souhaitée soit sélectionnée lorsque le ciblage passe d'un mode à l'autre (mode tactile ou gestes).
  • Utilisez attentivement requestFocus() et clearFocus() :
    • Lorsque vous appelez requestFocus(), assurez-vous que la vue doit vraiment être ciblé. Si la vue est en dehors de l'écran ou recouverte par une autre vue, des effets inattendus peuvent se produire lorsque des gestes déclenchent des rappels.
    • clearFocus() lance une recherche de ciblage pour trouver une autre vue appropriée. En fonction de la hiérarchie des vues, cette recherche peut nécessiter des calculs complexes. Elle peut également finir par attribuer le ciblage à une vue que vous ne vous attendiez pas à voir.
  • Les événements de touches sont d'abord envoyés à la vue ciblée dans la hiérarchie des vues. Si cette vue ne gère pas l'événement (par exemple, si elle renvoie false), celui-ci n'est pas envoyé à la vue parent, même s'il peut être ciblé et qu'il dispose d'un KeyListener. Au lieu de cela, l'événement est envoyé à l'activité actuelle, qui contient la hiérarchie des vues. Par conséquent, il peut être nécessaire d'identifier tous les événements au niveau supérieur, puis de transmettre les codes pertinents à tous les enfants. Vous pouvez également sous-classer l'activité et remplacer la méthode dispatchKeyEvent(KeyEvent event) pour vous assurer que les touches sont interceptées si nécessaire, ou qu'elles sont gérées lorsqu'elles ne le sont pas sur des couches inférieures.