Rotierende Eingabe mit „Compose“

Die Dreheingabe bezieht sich auf Eingaben von Teilen Ihrer Uhr, die sich drehen oder drehen. Durchschnittlich interagieren Nutzer nur wenige Sekunden mit ihrer Smartwatch. Sie können die Nutzererfahrung verbessern, indem Sie die Drehung verwenden, damit Nutzer schnell verschiedene Aufgaben erledigen können.

Die drei Hauptquellen für den Drehknopf bei den meisten Smartwatches sind die drehbare Taste an der Seite (RSB) und entweder ein physischer Rand oder ein Touchrand, also ein kreisförmiger Touchbereich um den Bildschirm. Das erwartete Verhalten kann je nach Art der Eingabe variieren. Unterstützen Sie jedoch bei allen wichtigen Interaktionen den Drehknopf.

Scrollen

Die meisten Nutzer erwarten, dass Apps die Scroll-Geste unterstützen. Wenn der Inhalt auf dem Bildschirm scrollt, geben Sie den Nutzenden als Reaktion auf Drehbewegungen visuelles Feedback. Das visuelle Feedback kann Positionsanzeigen für vertikales Scrollen oder Seitenindikatoren umfassen.

Implementieren Sie das Tool zum Scrollen mit Compose für Wear OS. In diesem Beispiel wird eine Anwendung mit einem Gerüst und einem ScalingLazyColumn beschrieben, das vertikal scrollt. Das Scaffold bietet die grundlegende Layoutstruktur für Wear OS-Apps und hat bereits einen Slot für eine Scrollanzeige. Erstellen Sie einen Positionsindikator basierend auf dem Listenstatusobjekt, um den Scrollfortschritt zu sehen. Scrollbare Ansichten, einschließlich ScalingLazyColumn, haben bereits einen scrollbaren Status zum Hinzufügen eines Drehknopfes. So empfangen Sie Dreh-Scroll-Ereignisse:

  1. Fordere den Fokus explizit mit FocusRequester an.
  2. Füge den onRotaryScrollEvent-Modifikator hinzu, um Ereignisse abzufangen, die das System generiert, wenn ein Nutzer die Krone dreht oder den Glasrand dreht. Jedes Drehereignis hat einen festgelegten Pixelwert und scrollt vertikal oder horizontal. Der Modifikator enthält auch einen Callback, der angibt, ob das Ereignis verarbeitet wurde, und stoppt die Ereignisweitergabe an seine übergeordneten Elemente.
val listState = rememberScalingLazyListState()

Scaffold(
    positionIndicator = {
        PositionIndicator(scalingLazyListState = listState)
    }
) {

    val focusRequester = rememberActiveFocusRequester()
    val coroutineScope = rememberCoroutineScope()

    ScalingLazyColumn(
        modifier = Modifier
            .onRotaryScrollEvent {
                coroutineScope.launch {
                    listState.scrollBy(it.verticalScrollPixels)

                    listState.animateScrollBy(0f)
                }
                true
            }
            .focusRequester(focusRequester)
            .focusable(),
        state = listState
    ) { ... }
}

Diskrete Werte

Mit Drehinteraktionen können Sie auch diskrete Werte anpassen, z. B. die Helligkeit in den Einstellungen anpassen oder beim Einstellen eines Weckers die Zahlen in der Zeitauswahl auswählen.

Ähnlich wie bei ScalingLazyColumn müssen Auswahl, Schieberegler, Stepper und andere zusammensetzbare Funktionen Fokus haben, um den Drehknopf zu empfangen. Bei mehreren scrollbaren Zielen auf dem Bildschirm, z. B. die Stunden und Minuten in der Zeitauswahl, erstellen Sie eine FocusRequester für jedes Ziel und bearbeiten Sie die Fokusänderung entsprechend, wenn der Nutzer auf Stunden oder Minuten tippt.

@Composable
fun TimePicker() {
    var selectedColumn by remember { mutableStateOf(0) }
    val focusRequester1 = remember { FocusRequester() }
    val focusRequester2 = remember { FocusRequester() }

    Row {
       Picker(...)
       Picker(...)
    }

    LaunchedEffect(selectedColumn) {
        listOf(focusRequester1,
               focusRequester2)[selectedColumn]
            .requestFocus()
    }
}

Benutzerdefinierte Aktionen

Sie können auch benutzerdefinierte Aktionen erstellen, die auf Drehköpfe in Ihrer App reagieren. Verwenden Sie beispielsweise den Drehknopf zum Heran- und Herauszoomen oder zum Steuern der Lautstärke in einer Medien-App.

Wenn Ihre Komponente Scrollereignisse wie die Lautstärkeregelung nicht nativ unterstützt, können Sie Scrollereignisse selbst verarbeiten.

// VolumeScreen.kt

val focusRequester: FocusRequester = remember { FocusRequester() }

Column(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            // handle rotary scroll events
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) { ... }

Erstellen Sie einen benutzerdefinierten Status, der im Ansichtsmodell verwaltet wird, und einen benutzerdefinierten Callback, der zum Verarbeiten von Scroll-Ereignissen verwendet wird.

// VolumeViewModel.kt

object VolumeRange(
    public val max: Int = 10
    public val min: Int = 0
)

val volumeState: MutableStateFlow<Int> = ...

fun onVolumeChangeByScroll(pixels: Float) {
    volumeState.value = when {
        pixels > 0 -> min (volumeState.value + 1, VolumeRange.max)
        pixels < 0 -> max (volumeState.value - 1, VolumeRange.min)
    }
}

Zur Vereinfachung wurden im vorherigen Beispiel Pixelwerte verwendet, die bei tatsächlicher Verwendung wahrscheinlich zu empfindlich sind.

Verwenden Sie den Callback, sobald Sie die Ereignisse erhalten, wie im folgenden Snippet gezeigt.

val focusRequester: FocusRequester = remember { FocusRequester() }
val volumeState by volumeViewModel.volumeState.collectAsState()

Column(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            volumeViewModel
                .onVolumeChangeByScroll(it.verticalScrollPixels)
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) { ... }

Zusätzliche Ressourcen

Sie können auch Horologist verwenden, ein Open-Source-Projekt von Google, das eine Reihe von Wear-Bibliotheken zur Verfügung stellt, die die von Compose für Wear OS und anderen Wear OS-APIs bereitgestellten Funktionen ergänzen. Der Horologe bietet Implementierungen für komplexe Anwendungsfälle und viele gerätespezifische Details.

Beispielsweise kann die Empfindlichkeit verschiedener Drehknopfquellen variieren. Für einen reibungslosen Übergang zwischen den Werten können Sie eine Ratenbegrenzung festlegen oder ein Andocken oder Animationen für den Übergang hinzufügen. So fühlt sich das Ändern der Geschwindigkeit für die Nutzer natürlicher an. Horologen enthalten Modifikatoren für scrollbare Komponenten und für diskrete Werte. Es umfasst auch Dienstprogramme zur Steuerung des Fokus und eine Audio-UI-Bibliothek zur Implementierung der Lautstärkeregelung mit Haptik.

Weitere Informationen finden Sie unter Horologe auf GitHub.