Entrada rotativa

Algunos dispositivos Wear OS contienen un botón lateral giratorio físico. Cuando el usuario gira el botón, se desplaza hacia arriba o hacia abajo por la vista actual de tu app. Este tipo de entrada se denomina entrada rotativa.

Nota: Esta guía se refiere principalmente al control de entradas rotativas a través de IUs basadas en View. Si deseas obtener más información sobre el control de entradas rotativas con Compose para Wear OS, consulta Entrada rotativa en Compose.

Muchos contenedores desplazables, como ScrollView, ListView, HorizontalScrollView y WearableRecyclerView, admiten entradas rotativas si tienen enfoque sin requerir ningún código específico de Wear OS. Tener el enfoque es un requisito previo importante porque, en Android 9 (nivel de API 28) y versiones posteriores, las vistas no reciben el enfoque de manera implícita.

Prácticas recomendadas sobre enfoque

Para responder a los eventos de entrada rotativos, un contenedor desplazable debe estar enfocado. Los eventos de entrada rotativa no aparecen en la jerarquía de vistas. Si no hay una vista enfocada o si la vista enfocada muestra false desde View.onGenericMotionEvent(), el evento se envía a Activity.onGenericMotionEvent().

Las siguientes son prácticas recomendadas para responder a eventos de entrada rotativos:

  • Ten en cuenta que, de forma predeterminada, iniciar una actividad o incluso presionar una vista no lo enfoca (aunque sea enfocable). Para que se enfoque la vista, esta debe usar la etiqueta <requestFocus /> o llamar a View.requestFocus() de forma manual.
  • Marca las vistas desplazables personalizadas como enfocables con android:focusable="true" y android:focusableInTouchMode="true".
  • Si se adjunta la vista desplazable después de Activity.onCreate() (por ejemplo, esperando a que finalice una solicitud de red antes de compilar la IU), llama a requestFocus() después de adjuntarla.
  • Si, en un principio, la vista desplazable es INVISIBLE o GONE, llama a requestFocus() cuando la establezcas en VISIBLE.
  • Si tu actividad contiene varias vistas desplazables, elige una para enfocarte mediante la etiqueta <requestFocus />. No se admite el desplazamiento anidado con el botón lateral giratorio.
  • Si la IU contiene alguna otra vista que enfoca cuando el usuario interactúa con ella, por ejemplo, un InputText, ofrécele al usuario una manera de restablecer el enfoque en la vista desplazable si pierde el foco escuchando presiones en la vista desplazable y llamando a requestFocus() en respuesta.

Comportamiento de rotación personalizado

Si tu vista desplazable no admite el desplazamiento de entrada rotativa de forma nativa, o si deseas usar la entrada rotativa para otro fin que no sea el desplazamiento (por ejemplo, acercar/alejar o girar diales), puedes controlar los eventos de desplazamiento por tu cuenta. Recuerda que debes asegurarte de que la vista se enfoque. De lo contrario, no se procesarán los eventos.

En el siguiente fragmento de código, se muestra cómo usar MotionEvent, InputDeviceCompat y ViewConfigurationCompat para agregar un desplazamiento personalizado a tu vista:

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;
  }
});

Cómo realizar pruebas con un emulador

Usa Android Emulator para simular el desplazamiento de entrada rotativa en un dispositivo Wear. Inicia tu app para Wear en el emulador cuando ejecutes tu proyecto o arrastra un archivo APK al emulador para instalarlo.

Para probar la entrada rotativa en el emulador, haz lo siguiente:

  1. Desde SDK Manager, usa la pestaña herramientas del SDK para obtener Android Emulator versión 26.0.3 o posterior.
  2. En Android Studio, selecciona Tools > Android > Administrador de AVD. Crea un dispositivo para Wear nuevo con un nivel de API 25 o uno superior.
  3. Ejecuta el emulador desde Android Studio.
  4. Haz clic en el menú ampliado de tres puntos ubicado en la parte inferior de la barra de herramientas del emulador. En la ventana nueva, haz clic en la pestaña Rotary input para abrir la interfaz de entrada rotativa y probar el desplazamiento de entrada rotativa.

El siguiente video muestra la entrada rotativa en el emulador: