Su Wear OS 7 (livello API 37) e versioni successive, un framework per le gesture con una sola mano, insieme a un'API che fa parte di Compose for Wear OS, consente agli utenti di interagire con la tua app senza toccare lo schermo.
Sebbene inizialmente supportato sui dispositivi Pixel Watch (Pixel Watch 3 e modelli successivi), il framework è disponibile per tutti gli OEM. Se adotti questa API, il supporto dei gesti della tua app viene scalato automaticamente nell'ecosistema man mano che il supporto hardware si espande.
Per aiutare gli utenti a scoprire i gesti disponibili senza ingombrare l'interfaccia utente, il framework Wear OS fornisce indicatori di gesti animati. Questi suggerimenti visivi evidenziano dove è possibile eseguire un gesto, mentre il sistema gestisce automaticamente la cadenza di visualizzazione e la frequenza di disattivazione dell'audio in base alle preferenze dell'utente.
Gesti e azioni supportati
Il framework dei gesti di Wear OS supporta due tipi di gesti:
- Azione principale (doppio pizzico): corrisponde all'azione principale su una schermata, ad esempio rispondere a una chiamata o attivare/disattivare la riproduzione dei contenuti multimediali.
- Azione di chiusura (rotazione del polso): corrisponde alla navigazione all'indietro, alla chiusura di una finestra di dialogo o all'annullamento di una richiesta.
Configurare i gesti in Scrivi
Sebbene l'API per le gesture a una mano possa migliorare la tua UI, è importante tenere presente che alcuni produttori di hardware e OEM non supportano queste gesture. Se l'API rileva che la tua app è in esecuzione su uno di questi dispositivi non supportati, la libreria diventa automaticamente autonoma senza influire sulle interazioni touch standard.
Come per i comportamenti standard di Compose, puoi attivare i gesti a una mano sugli elementi
dell'interfaccia utente utilizzando i modificatori. Configura i gesti della tua app
in base all'azione da eseguire, ovvero principale o chiusura, e a un gestureId
per coordinarsi con le preferenze dell'utente a livello di sistema, come la cadenza di visualizzazione dei suggerimenti
e la disattivazione della frequenza. Questa configurazione viene espressa creando un oggetto OneHandedGestureConfiguration. Ti consigliamo di utilizzare la funzione rememberOneHandedGestureConfiguration per crearlo. In OneHandedGestureConfiguration puoi anche specificare la priorità dei gesti.
La funzione rememberOneHandedGestureConfiguration tiene traccia della cronologia delle interazioni utente tra le ricomposizioni senza esporre lo stato dell'applicazione. Una volta creata la configurazione, l'app deve passarla a
Modifier.oneHandedGesture sul composable interattivo.
Per aiutare gli utenti a scoprire i gesti disponibili, la libreria fornisce il metodo
OneHandedGestureClickIndicator. Questo metodo funge da wrapper che
sostituisce i contenuti sottostanti per indicare all'utente che è disponibile
un'azione di movimento.
Componenti interattivi
Per attivare i gesti su un controllo interattivo come un pulsante, crea una configurazione che specifichi OneHandedGestureAction.Primary e applica il modificatore oneHandedGesture. Passa lo stesso MutableInteractionSource sia al controllo che al modificatore in modo che gli eventi di movimento emettano un feedback visivo di pressione sul controllo.
Per attivare l'indicatore dei gesti, crea e memorizza un'istanza di
OneHandedGestureClickIndicatorState. Poi, per attivare il feedback visivo,
chiama showIndicator all'interno del callback onGestureAvailable fornito dal
modificatore oneHandedGesture, che segnala al sistema che si è verificato un evento
di indicazione. Una volta chiamato, il componente sostituisce brevemente il suo normale
contenuto con un'animazione del gesto.
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()) } }
Contenitori scorrevoli
Per le schermate o gli elenchi scorrevoli, crea una configurazione che specifichi
OneHandedGestureAction.Primary e applica il modificatore oneHandedGesture al
contenitore, chiamando un helper di scorrimento come scrollDown.
Per fornire un feedback visivo per le azioni di scorrimento, puoi utilizzare
OneHandedGestureScrollIndicator. Questo componente funziona
come indicatore di scorrimento standard che mostra la posizione di scorrimento, ma può anche
indicare all'utente che è disponibile un gesto di scorrimento. Questo indicatore viene
in genere passato allo slot scrollIndicator di un
ScreenScaffold ed è accoppiato allo stato di un
contenitore scorrevole, ad esempio un TransformingLazyColumn. Osserva anche un
OneHandedGestureScrollIndicatorState per gestire le transizioni visive.
Per attivare il feedback visivo, chiama showIndicator in questo stato, in genere
all'interno del callback onGestureAvailable del modificatore oneHandedGesture.
Una volta attivato, l'indicatore sostituisce temporaneamente il suo stato visivo standard
con una sequenza di animazione dei gesti per avvisare l'utente.
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)) } } }
Combinare più gesti
Puoi configurare sia un gesto di scorrimento sia un gesto di clic con la stessa
azione principale aggiungendo gesturePriority all'oggetto
OneHandedGestureConfiguration:
OneHandedGesturePriority.Clickable(massima): Assegna ai controlli interattivi, ad esempio quelli di tipoButtonoCard, in modo che acquisiscano i gesti quando sono visibili sullo schermo.OneHandedGesturePriority.Scrollable(media): Assegna a contenitori scorrevoli o impaginabili in modo che cedano il passo a elementi secondari selezionabili, ma scorra quando non è visibile alcun controllo selezionabile.OneHandedGesturePriority.Unspecified(più bassa): Una priorità non assegnata. Questo è il valore predefinito per un gesto che non ha unpriorityimpostato.
Se imposti in modo esplicito priority = OneHandedGesturePriority.Clickable
su un pulsante interno e priority = OneHandedGesturePriority.Scrollable
sull'elenco principale, il sistema può mostrare questo comportamento di priorità dei gesti.
Quando l'utente attiva l'azione principale con il gesto con una sola mano, l'elenco viene prima scorre verso il basso fino a quando il pulsante non è visibile, poi viene acquisita l'azione di clic del pulsante.
Testare ed eseguire il debug dei gesti con ADB
Puoi testare i gesti con una sola mano su un dispositivo fisico o un emulatore
senza eseguire movimenti fisici del polso utilizzando Android Debug
Bridge (adb) e il servizio di sistema IWearGestureService.
Attivare la simulazione dei gesti
Prima di simulare i gesti utilizzando ADB, configura le impostazioni del dispositivo e gli override dei vincoli:
Verifica che sul dispositivo Wear OS sia installato Wear OS 7 (livello API 37) o versioni successive:
adb shell getprop ro.build.version.sdkSe esegui il test su un dispositivo fisico che non è al tuo polso o è appoggiato su un caricabatterie, esegui l'override del vincolo di non indossato in modo che il framework dei gesti rimanga attivo:
adb shell cmd IWearGestureService override-constraints offbody-state
Attivare eventi di gesture utilizzando ADB
Per simulare il gesto Doppio pizzico (che è l'azione Primary sugli smartwatch Pixel), esegui questo comando della shell ADB:
adb shell cmd IWearGestureService gesture DoublePinch
Per simulare il gesto Rotazione del polso (che è l'azione Dismiss sugli smartwatch Pixel), esegui questo comando della shell ADB:
adb shell cmd IWearGestureService gesture WristTurn
Reimpostare il monitoraggio dei suggerimenti per i gesti
Il sistema tiene traccia della cronologia delle interazioni dell'utente e mostra suggerimenti per i gesti mobili in base all'impostazione della cadenza globale (ad esempio Sempre o Giornalmente). Quando esegui il debug degli indicatori di gesture della tua app, reimposta questa cronologia di monitoraggio in modo che i suggerimenti vengano visualizzati di nuovo per il tuo pacchetto:
Su build o emulatori
userdebug:adb shell cmd IWearGestureService hint clear <your_package_name>Nelle build retail (
user):Sui dispositivi commerciali senza accesso root,
hint clearè bloccato dalle autorizzazioni di sistema. Cancella i dati locali dell'app per reimpostare la scoperta dei suggerimenti:adb shell pm clear <your_package_name>
Ripristinare i vincoli predefiniti
Per reimpostare tutti gli override dei vincoli di debug al termine del test:
adb shell cmd IWearGestureService override-constraints reset
Risolvere i problemi di iniezione di gesti
Se la tua app non riceve gesti simulati:
Verifica che lo schermo dello smartwatch sia attivo e acceso. Il framework dei gesti non invia gesti alle applicazioni quando lo schermo è spento o in modalità Ambient. Per attivare il display utilizzando ADB, esegui:
adb shell input keyevent KEYCODE_WAKEUPControlla se la tua app è registrata come abbonato attivo ai gesti e attualmente ha il focus della finestra:
adb shell cmd IWearGestureService get-active-gestures -readableQuando la schermata dei gesti dell'app è in primo piano e lo schermo è attivo, questo comando restituisce
[DoublePinch]o[DoublePinch, WristTurn]. Se viene restituito un elenco vuoto ([]), controlla se la finestra è attiva o se i vincoli fuori dal corpo bloccano l'attivazione.Controlla lo stato del servizio di gesture interno e i token abbonati attivi:
adb shell dumpsys IWearGestureService
Risorse aggiuntive
Per indicazioni di progettazione su quando e dove utilizzare i gesti con una mano, consulta Gesti con una mano.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Guida alla progettazione di gesti con una sola mano