A partir de Wear OS 7 (nivel de API 37), un framework de gestos con una mano, junto con una API que forma parte de Compose para Wear OS, permite a los usuarios interactuar con tu app sin tocarla.
Si bien inicialmente se admitía en dispositivos Pixel Watch (Pixel Watch 3 y modelos posteriores), el framework está disponible para todos los OEMs. Cuando adoptas esta API, la compatibilidad con gestos de tu app se ajusta automáticamente en todo el ecosistema a medida que se expande la compatibilidad con hardware.
Para ayudar a los usuarios a descubrir los gestos disponibles sin desordenar la IU, el framework de Wear OS proporciona indicadores de gestos animados. Estas sugerencias visuales destacan dónde se puede realizar un gesto, mientras que el sistema administra automáticamente su cadencia de visualización y frecuencia de silenciamiento según las preferencias del usuario.
Gestos y acciones compatibles
El framework de gestos de Wear OS admite dos tipos de gestos:
- Acción principal (doble pellizco): Se asigna a la acción principal en una pantalla, como responder una llamada o activar o desactivar la reproducción de contenido multimedia.
- Acción de descartar (giro de muñeca): Se asigna a la navegación hacia atrás, el descarte de un diálogo o la cancelación de una instrucción.
Configura gestos en Compose
Si bien la API de gestos con una mano puede mejorar tu IU, es importante tener en cuenta que algunos OEMs y hardware no admiten estos gestos. Si la API detecta que tu app se ejecuta en uno de estos dispositivos no compatibles, la biblioteca no realiza ninguna operación automáticamente sin afectar las interacciones táctiles estándar.
Al igual que con los comportamientos estándar de Compose, puedes habilitar los gestos con una mano en los elementos de la IU
con modificadores. Configuras los gestos de tu app según la acción que se realizará (principal o descartar) y un gestureId para coordinar con las preferencias del usuario a nivel del sistema, como la cadencia de visualización de sugerencias y el silenciamiento de frecuencia. Para expresar esta configuración, crea un
OneHandedGestureConfiguration objeto. Te recomendamos que uses la
rememberOneHandedGestureConfiguration función para crearlo. En OneHandedGestureConfiguration, también puedes proporcionar la prioridad del gesto.
La función rememberOneHandedGestureConfiguration realiza un seguimiento del historial de interacción del usuario en las recomposiciones sin exponer el estado de la aplicación. Una vez que tu app haya creado la configuración, debe pasarla a Modifier.oneHandedGesture en tu elemento componible interactivo.
Para ayudar a los usuarios a descubrir los gestos disponibles, la biblioteca proporciona el método OneHandedGestureClickIndicator. Este método actúa como un wrapper que reemplaza su contenido subyacente para indicarle al usuario que hay una acción de gesto disponible.
Componentes interactivos
Para habilitar gestos en un control interactivo, como un botón, crea una configuración que especifique OneHandedGestureAction.Primary y aplica el modificador oneHandedGesture. Pasa el mismo MutableInteractionSource al control y al modificador para que los eventos de gestos emitan comentarios visuales de presión en el control.
Para habilitar el indicador de gestos, crea y recuerda una instancia de OneHandedGestureClickIndicatorState. Luego, para activar los comentarios visuales, llama a showIndicator dentro de la devolución de llamada onGestureAvailable que proporciona el modificador oneHandedGesture, que le indica al sistema que se produjo un evento de indicación. Una vez que se llama, el componente reemplaza brevemente su contenido normal por una animación de gestos.
var isPlaying by remember { mutableStateOf(false) } val onClick = { isPlaying = !isPlaying } val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary ) val indicatorState = remember { OneHandedGestureClickIndicatorState() } val coroutineScope = rememberCoroutineScope() val interactionSource = remember { MutableInteractionSource() } Button( onClick = onClick, interactionSource = interactionSource, modifier = Modifier .fillMaxWidth() .oneHandedGesture( gestureConfiguration = gestureConfig, interactionSource = interactionSource, onGestureLabel = if (isPlaying) "pause" else "play", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = onClick ) ) { OneHandedGestureClickIndicator( gestureConfiguration = gestureConfig, state = indicatorState ) { Text(if (isPlaying) "Pause" else "Play", modifier = Modifier.fillMaxWidth()) } }
Contenedores desplazables
Para pantallas o listas desplazables, crea una configuración que especifique OneHandedGestureAction.Primary y aplica el modificador oneHandedGesture a tu contenedor, llamando a un asistente de desplazamiento, como scrollDown.
Para proporcionar comentarios visuales para las acciones de desplazamiento, puedes usar el
OneHandedGestureScrollIndicator. Este componente funciona como un indicador de desplazamiento estándar que muestra la posición de desplazamiento, pero también puede indicar que hay un gesto de desplazamiento disponible para el usuario. Por lo general, este indicador se
pasa a la ranura scrollIndicator de un
ScreenScaffold y se vincula con el estado de un
contenedor desplazable, como un TransformingLazyColumn. También observa un OneHandedGestureScrollIndicatorState para administrar sus transiciones visuales.
Para activar los comentarios visuales, llama a showIndicator en este estado, por lo general, dentro de la devolución de llamada onGestureAvailable del modificador oneHandedGesture.
Una vez activado, el indicador reemplaza temporalmente su estado visual estándar por una secuencia de animación de gestos para alertar al usuario.
val scrollState = rememberTransformingLazyColumnState() val gestureConfig = rememberOneHandedGestureConfiguration( action = OneHandedGestureAction.Primary, priority = OneHandedGesturePriority.Scrollable ) val indicatorState = remember(gestureConfig) { OneHandedGestureScrollIndicatorState() } val coroutineScope = rememberCoroutineScope() ScreenScaffold( scrollState = scrollState, scrollIndicator = { OneHandedGestureScrollIndicator( gestureConfiguration = gestureConfig, indicatorState = indicatorState, scrollState = scrollState, modifier = Modifier.align(Alignment.CenterEnd) ) } ) { contentPadding -> TransformingLazyColumn( state = scrollState, contentPadding = contentPadding, modifier = Modifier .fillMaxSize() .oneHandedGesture( gestureConfiguration = gestureConfig, onGestureLabel = "scroll", onGestureAvailable = { coroutineScope.launch { indicatorState.showIndicator() } }, onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) } ) ) { items(10) { index -> Text("Item $index", modifier = Modifier.padding(8.dp)) } } }
Combina varios gestos
Puedes configurar un gesto de desplazamiento y un gesto de clic con la misma acción principal agregando gesturePriority a tu objeto OneHandedGestureConfiguration:
OneHandedGesturePriority.Clickable(más alta): Asigna a controles interactivos, como aquellos con tipoButtonoCard, para que capturen gestos cuando estén visibles en la pantalla.OneHandedGesturePriority.Scrollable(media): Asigna a contenedores desplazables o paginables para que cedan a elementos secundarios en los que se puede hacer clic, pero se desplacen cuando no se vea ningún control en el que se pueda hacer clic.OneHandedGesturePriority.Unspecified(más baja): Una prioridad no asignada. Este es el valor predeterminado para un gesto que no tiene unpriorityestablecido.
Si estableces explícitamente priority = OneHandedGesturePriority.Clickable en un botón interno y priority = OneHandedGesturePriority.Scrollable en su lista superior, el sistema puede mostrar este comportamiento de prioridad de gestos.
Cuando el usuario activa la acción principal con el gesto con una mano, primero desplaza la lista hacia abajo hasta que el botón esté visible. Luego, captura la acción de clic del botón.
Prueba y depura gestos con ADB
Puedes probar los gestos con una mano en un dispositivo físico o en un emulador sin realizar movimientos físicos de la muñeca con Android Debug Bridge (adb) y el servicio del sistema IWearGestureService.
Habilita la simulación de gestos
- Verifica que tu dispositivo Wear OS ejecute Wear OS 7 (nivel de API 37) y versiones posteriores.
- Si realizas pruebas en un dispositivo físico que no está en la muñeca o en un cargador, anula el estado del sensor fuera del cuerpo para que el dispositivo permanezca activo:
adb shell cmd sensorservice set-off-body-state 0
Activa eventos de gestos con ADB
Para simular el gesto de doble pellizco (que es la acción Primary en los relojes Pixel), ejecuta el siguiente comando de shell de ADB:
adb shell cmd IWearGestureService gesture 1
Para simular el gesto de giro de muñeca (que es la acción Dismiss en los relojes Pixel), ejecuta el siguiente comando de shell de ADB:
adb shell cmd IWearGestureService gesture 2
Restablece el seguimiento de sugerencias de gestos
El sistema realiza un seguimiento del historial de interacción del usuario y muestra sugerencias de gestos flotantes según la configuración de cadencia global (como Siempre o Diario). Cuando depures los indicadores de gestos de tu app, restablece este historial de seguimiento para que las sugerencias vuelvan a aparecer en tu paquete:
adb shell cmd IWearGestureService hint clear <your_package_name>
Para restablecer el estado del sensor fuera del cuerpo cuando termines de realizar pruebas, haz lo siguiente:
adb shell cmd sensorservice reset-off-body-state
Recursos adicionales
Para obtener orientación sobre el diseño de cuándo y dónde usar gestos con una mano, consulta Gestos con una mano.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Guía de diseño de gestos con una mano