Saisie par dispositif rotatif

Certains appareils Wear OS disposent d'un bouton latéral rotatif. Lorsque l'utilisateur tourne le bouton, la vue active de votre application défile vers le haut ou vers le bas. Ce type d'entrée est appelé saisie par dispositif rotatif.

Remarque : Ce guide concerne principalement la gestion de la saisie par dispositif rotatif à l'aide d'interfaces utilisateur basées sur les vues. Pour en savoir plus sur la gestion de la saisie par dispositif rotatif à l'aide de Compose pour Wear OS, consultez la page Saisie par dispositif rotatif sur Compose.

De nombreux conteneurs à défilement, tels que ScrollView, ListView, HorizontalScrollView et WearableRecyclerView, acceptent les saisies par dispositif rotatif si celles-ci sont ciblées, sans nécessiter de code spécifique à Wear OS. Le ciblage est une condition préalable déterminante, car sur Android 9 (niveau d'API 28) ou version ultérieure, les vues ne sont pas implicitement activées.

Bonnes pratiques sur le ciblage

Pour répondre à des événements de saisie par dispositif rotatif, un conteneur à défilement doit être sélectionné. Ces événements ne remontent pas dans la hiérarchie des vues. Si aucune vue active n'est disponible ou si la vue ciblée renvoie false à partir de View.onGenericMotionEvent(), l'événement est envoyé à Activity.onGenericMotionEvent().

Vous trouverez ci-dessous les bonnes pratiques à suivre pour répondre aux événements de saisie par dispositif rotatif :

  • Par défaut, le fait de lancer une activité, voire d'appuyer sur une vue, ne permet pas de la cibler, même si elle est sélectionnable. Pour cibler la vue, elle doit utiliser la balise <requestFocus /> ou appeler manuellement View.requestFocus().
  • Marquez les vues déroulantes personnalisées comme sélectionnables avec android:focusable="true" et android:focusableInTouchMode="true".
  • Si la vue déroulante est associée après Activity.onCreate() (par exemple, dans l'attente de la fin d'une requête réseau avant de créer votre UI), appelez requestFocus() après l'avoir associée.
  • Si la vue déroulante est initialement INVISIBLE ou GONE, appelez requestFocus() lorsque vous la définissez sur VISIBLE.
  • Si votre activité contient plusieurs vues à défilement, sélectionnez celle que vous souhaitez utiliser via la balise <requestFocus />. Le défilement intégré n'est pas compatible avec le bouton rotatif latéral.
  • Si votre interface utilisateur contient une autre vue qui s'active lorsque l'utilisateur interagit avec elle (par exemple, une zone InputText), donnez-lui la possibilité de restaurer la vue à défilement si elle n'est plus ciblée en écoutant les gestes de pression sur la vue à défilement et en appelant requestFocus() en réponse.

Comportement rotatif personnalisé

Si votre vue à défilement n'est pas compatible de manière native avec le défilement via un dispositif rotatif, ou si vous souhaitez utiliser la saisie par dispositif rotatif pour autre chose que le défilement (par exemple, pour faire un zoom avant ou arrière ou pour faire avancer ou reculer l'heure), vous pouvez gérer les événements de défilement vous-même. Rappelez-vous que la vue doit pouvoir être ciblée. Dans le cas contraire, les événements ne seront pas concluants.

L'extrait de code suivant montre comment utiliser MotionEvent, InputDeviceCompat et ViewConfigurationCompat pour ajouter un défilement personnalisé à votre vue :

Kotlin

myView.setOnGenericMotionListener { v, ev ->
  if (ev.action == MotionEvent.ACTION_SCROLL &&
      ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
  ) {
    // Don't forget the negation here
    val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
        ViewConfigurationCompat.getScaledVerticalScrollFactor(
             ViewConfiguration.get(context), context
        )
    // Swap these axes to scroll horizontally instead
    v.scrollBy(0, delta.roundToInt())
    true
  } else {
    false
  }
}

Java

myView.setOnGenericMotionListener(new View.OnGenericMotionListener() {
  @Override
  public boolean onGenericMotion(View v, MotionEvent ev) {
    if (ev.getAction() == MotionEvent.ACTION_SCROLL &&
        ev.isFromSource(InputDeviceCompat.SOURCE_ROTARY_ENCODER)
    ) {
      // Don't forget the negation here
      float delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) *
          ViewConfigurationCompat.getScaledVerticalScrollFactor(
               ViewConfiguration.get(context), context
          );

      // Swap these axes to scroll horizontally instead
      v.scrollBy(0, Math.round(delta));

      return true;
    }
    return false;
  }
});

Effectuer des tests à l'aide d'un émulateur

Utilisez l'émulateur Android pour simuler un défilement via le dispositif rotatif sur un appareil Wear. Lancez votre application Wear sur l'émulateur pour exécuter votre projet ou faites glisser un fichier APK sur l'émulateur pour l'installer.

Pour tester la saisie par dispositif rotatif sur l'émulateur, procédez comme suit :

  1. Dans le SDK Manager, accédez à l'onglet SDK Tools pour télécharger Android Emulator 26.0.3 ou une version ultérieure.
  2. Dans Android Studio, sélectionnez Tools > Android > AVD Manager (Outils > Android > AVD Manager). Créez un appareil Wear avec l'API 25 ou version ultérieure.
  3. Exécutez l'émulateur depuis Android Studio.
  4. Cliquez sur le menu à trois points en bas de la barre d'outils de l'émulateur. Cliquez sur l'onglet Rotary input (Saisie par dispositif rotatif) dans la nouvelle fenêtre pour ouvrir l'interface correspondante, puis testez le défilement via ce dispositif.

La vidéo suivante présente la saisie par dispositif rotatif dans l'émulateur :