Unter Wear OS 7 (API-Level 37) und höher können Nutzer über ein Framework für einhändige Gesten und eine API, die Teil von Compose für Wear OS ist, ohne Berührung mit Ihrer App interagieren.
Das Framework wird zwar anfänglich auf Pixel Watch-Geräten (Pixel Watch 3 und höher) unterstützt, ist aber für alle OEMs verfügbar. Wenn Sie diese API verwenden, wird die Gestenunterstützung Ihrer App automatisch auf das gesamte Ökosystem ausgeweitet, wenn die Hardwareunterstützung erweitert wird.
Damit Nutzer verfügbare Gesten entdecken können, ohne die Benutzeroberfläche zu überladen, bietet das Wear OS-Framework animierte Gestenanzeigen. Diese visuellen Hinweise zeigen, wo eine Geste ausgeführt werden kann. Das System verwaltet die Anzeigehäufigkeit und die Häufigkeit der Stummschaltung automatisch gemäß den Nutzereinstellungen.
Unterstützte Gesten und Aktionen
Das Wear OS-Framework für Touch-Gesten unterstützt zwei Arten von Touch-Gesten:
- Primäre Aktion (Doppeltes Zusammenziehen): Wird der Hauptaktion auf einem Bildschirm zugeordnet, z. B. dem Annehmen eines Anrufs oder dem Ein- und Ausschalten der Medienwiedergabe.
- Aktion „Schließen“ (Handgelenk drehen): Zurücknavigation, Schließen eines Dialogfelds oder Abbrechen einer Aufforderung.
Touch-Gesten in Compose konfigurieren
Die API für einhändige Gesten kann zwar die Benutzeroberfläche verbessern, aber Sie sollten beachten, dass einige Hardware und OEMs diese Gesten nicht unterstützen. Wenn die API erkennt, dass deine App auf einem dieser nicht unterstützten Geräte ausgeführt wird, wird die Bibliothek automatisch deaktiviert, ohne dass die standardmäßigen Touch-Interaktionen beeinträchtigt werden.
Wie bei Standard-Compose-Verhalten aktivieren Sie einhändige Gesten für UI-Elemente mithilfe von Modifikatoren. Du konfigurierst die Gesten deiner App entsprechend der auszuführenden Aktion – entweder primär oder schließen – und einen gestureId, um die Gesten mit den Nutzereinstellungen auf Systemebene abzustimmen, z. B. mit der Häufigkeit der Anzeige von Hinweisen und der Stummschaltung. Sie drücken diese Konfiguration aus, indem Sie ein OneHandedGestureConfiguration-Objekt erstellen. Wir empfehlen, es mit der Funktion rememberOneHandedGestureConfiguration zu erstellen. In der OneHandedGestureConfiguration können Sie auch die Gestenpriorität angeben.
Die Funktion rememberOneHandedGestureConfiguration verfolgt den Verlauf der Nutzerinteraktionen über Neuzusammensetzungen hinweg, ohne den Anwendungsstatus offenzulegen. Nachdem Ihre App die Konfiguration erstellt hat, sollte sie die Konfiguration an Modifier.oneHandedGesture in Ihrer interaktiven komponierbaren Funktion übergeben.
Damit Nutzer verfügbare Gesten leichter finden, bietet die Bibliothek die Methode OneHandedGestureClickIndicator. Diese Methode fungiert als Wrapper, der den zugrunde liegenden Inhalt ersetzt, um dem Nutzer anzuzeigen, dass eine Gestenaktion verfügbar ist.
Interaktive Komponenten
Wenn Sie Gesten für ein interaktives Steuerelement wie eine Schaltfläche aktivieren möchten, erstellen Sie eine Konfiguration, in der OneHandedGestureAction.Primary angegeben ist, und wenden Sie den Modifikator oneHandedGesture an. Übergebe dieselbe MutableInteractionSource an das Steuerelement und den Modifikator, damit Gestenereignisse visuelles Feedback zum Drücken auf das Steuerelement ausgeben.
Wenn du die Gestenanzeige aktivieren möchtest, erstelle eine Instanz von OneHandedGestureClickIndicatorState und merke sie dir. Rufen Sie dann showIndicator im onGestureAvailable-Callback auf, der vom oneHandedGesture-Modifikator bereitgestellt wird, um das visuelle Feedback auszulösen. Dadurch wird dem System signalisiert, dass ein Indikationsereignis aufgetreten ist. Nach dem Aufruf ersetzt die Komponente ihren normalen Inhalt kurz durch eine Gestenanimation.
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()) } }
Scrollbare Container
Erstelle für scrollbare Bildschirme oder Listen eine Konfiguration, die OneHandedGestureAction.Primary angibt, und wende den Modifikator oneHandedGesture auf deinen Container an. Rufe dabei einen Scroll-Helper wie scrollDown auf.
Wenn du visuelles Feedback für Scrollaktionen geben möchtest, kannst du OneHandedGestureScrollIndicator verwenden. Diese Komponente fungiert als Standard-Scrollanzeige, die die Scrollposition anzeigt, kann aber auch darauf hinweisen, dass dem Nutzer eine Scroll-Geste zur Verfügung steht. Diese Anzeige wird normalerweise an den Slot scrollIndicator eines ScreenScaffold übergeben und ist mit dem Status eines scrollbaren Containers wie TransformingLazyColumn verknüpft. Außerdem wird ein OneHandedGestureScrollIndicatorState beobachtet, um die visuellen Übergänge zu verwalten.
Wenn du das visuelle Feedback auslösen möchtest, rufe showIndicator für diesen Status auf. Das geschieht normalerweise im onGestureAvailable-Callback des oneHandedGesture-Modifikators.
Sobald die Anzeige ausgelöst wird, wird ihr Standardzustand vorübergehend durch eine Gestenanimationssequenz ersetzt, um den Nutzer zu benachrichtigen.
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)) } } }
Mehrere Gesten kombinieren
Sie können sowohl eine Scroll- als auch eine Klick-Geste mit derselben primären Aktion konfigurieren, indem Sie gesturePriority zu Ihrem OneHandedGestureConfiguration-Objekt hinzufügen:
OneHandedGesturePriority.Clickable(höchste): Wird interaktiven Steuerelementen zugewiesen, z. B. solchen mit dem TypButtonoderCard, damit sie Gesten erfassen, wenn sie auf dem Bildschirm sichtbar sind.OneHandedGesturePriority.Scrollable(mittel): Weisen Sie diese Rolle scrollbaren oder seitenweise scrollbaren Containern zu, damit sie anklickbaren untergeordneten Elementen weichen, aber scrollen, wenn kein anklickbares Steuerelement sichtbar ist.OneHandedGesturePriority.Unspecified(niedrigste): Eine nicht zugewiesene Priorität. Dies ist der Standardwert für eine Geste, für die keinpriorityfestgelegt ist.
Wenn Sie priority = OneHandedGesturePriority.Clickable explizit für eine innere Schaltfläche und priority = OneHandedGesturePriority.Scrollable für die übergeordnete Liste festlegen, kann das System dieses Verhalten mit Gestenpriorität anzeigen.
Wenn der Nutzer die primäre Aktion mit der einhändigen Geste auslöst, wird die Liste zuerst nach unten gescrollt, bis die Schaltfläche sichtbar ist. Anschließend wird die Klickaktion der Schaltfläche erfasst.
Gesten mit ADB testen und Fehler beheben
Du kannst einhändige Gesten auf einem physischen Gerät oder Emulator testen, ohne physische Handgelenksbewegungen auszuführen. Verwende dazu die Android Debug Bridge (adb) und den Systemdienst IWearGestureService.
Gestensimulation aktivieren
Bevor Sie Gesten mit ADB simulieren, konfigurieren Sie die Geräteeinstellungen und die Einschränkungsüberschreibungen:
Prüfe, ob auf deinem Wear OS-Gerät Wear OS 7 (API-Level 37) oder höher ausgeführt wird:
adb shell getprop ro.build.version.sdkWenn du auf einem physischen Gerät testest, das sich nicht an deinem Handgelenk befindet oder auf einem Ladegerät liegt, überschreibe die Einschränkung „Nicht am Körper“, damit das Gesten-Framework aktiv bleibt:
adb shell cmd IWearGestureService override-constraints offbody-state
Gestenereignisse mit ADB auslösen
Führe den folgenden ADB-Shell-Befehl aus, um die Geste Doppeltes Zusammenführen zu simulieren (die Aktion Primary auf Pixel Watches):
adb shell cmd IWearGestureService gesture DoublePinch
Führen Sie den folgenden ADB-Shell-Befehl aus, um die Geste Handgelenk drehen zu simulieren, die auf Pixel Watches der Aktion Dismiss entspricht:
adb shell cmd IWearGestureService gesture WristTurn
Tracking von Gestenhinweisen zurücksetzen
Das System verfolgt den Verlauf der Nutzerinteraktionen und zeigt schwebende Gestenhinweise basierend auf der globalen Einstellung für die Häufigkeit an (z. B. Immer oder Täglich). Wenn du die Gestenanzeigen deiner App debuggst, setze diesen Tracking-Verlauf zurück, damit Hinweise für dein Paket wieder angezeigt werden:
Auf
userdebug-Builds oder Emulatoren:adb shell cmd IWearGestureService hint clear <your_package_name>Auf Retail-Builds (
user):Auf kommerziellen Geräten ohne Root-Zugriff wird
hint cleardurch Systemberechtigungen blockiert. Löschen Sie die lokalen Daten der App, um die Tippsuche zurückzusetzen:adb shell pm clear <your_package_name>
Standardeinschränkungen wiederherstellen
So setzen Sie alle Debug-Einschränkungsüberschreibungen zurück, wenn Sie mit dem Testen fertig sind:
adb shell cmd IWearGestureService override-constraints reset
Fehlerbehebung bei der Gesteneinschleusung
Wenn Ihre App keine simulierten Gesten empfängt:
Prüfe, ob das Display der Smartwatch aktiviert und eingeschaltet ist. Das Gesten-Framework sendet keine Gesten an Anwendungen, wenn das Display ausgeschaltet ist oder sich im Inaktivmodus befindet. Führe den folgenden Befehl aus, um das Display mit ADB zu aktivieren:
adb shell input keyevent KEYCODE_WAKEUPPrüfen Sie, ob Ihre App als aktiver Gestenabonnent registriert ist und derzeit den Fensterfokus hat:
adb shell cmd IWearGestureService get-active-gestures -readableWenn der Gestenbildschirm Ihrer App im Vordergrund und der Bildschirm aktiv ist, gibt dieser Befehl
[DoublePinch]oder[DoublePinch, WristTurn]zurück. Wenn eine leere Liste ([]) zurückgegeben wird, prüfen Sie, ob das Fenster im Fokus ist oder ob die Aktivierung durch Einschränkungen blockiert wird, die nicht am Körper getragen werden.Prüfe den Status des internen Gestendienstes und die aktiven Abonnenten-Tokens:
adb shell dumpsys IWearGestureService
Zusätzliche Ressourcen
Designhinweise dazu, wann und wo Einhandgesten verwendet werden sollten, findest du unter Einhandgesten.
Empfehlungen für Sie
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Designleitfaden für Einhandgesten