Rotierende Eingabe mit „Compose“


Drehknopf bezieht sich auf Eingaben über Teile Ihrer Smartwatch, die sich drehen. Im Durchschnitt interagieren Nutzer nur wenige Sekunden mit ihrer Smartwatch. Sie können die Nutzerfreundlichkeit verbessern, indem Sie einen Drehknopf verwenden, mit dem Nutzer schnell verschiedene Aufgaben erledigen können.

Die drei Hauptquellen für die Dreheingabe bei den meisten Smartwatches sind die drehbare Seitentaste (RSB) und entweder eine physische Lünette oder eine Touch-Lünette, eine kreisförmige Touchzone um den Bildschirm herum. Das erwartete Verhalten kann je nach Eingabetyp variieren. Achten Sie jedoch darauf, die Drehknopf-Eingabe für alle wichtigen Interaktionen zu unterstützen.

Scrollen

Die meisten Nutzer erwarten, dass Apps das Scrollen per Wisch unterstützen. Während der Inhalt auf dem Bildschirm scrollt, geben Sie den Nutzern visuelles Feedback als Reaktion auf Drehknopfinteraktionen. Visuelles Feedback kann Scrollindikatoren für das vertikale Scrollen oder Seitenindikatoren umfassen.

ScalingLazyColumn, TransformingLazyColumn und Picker unterstützen standardmäßig das Scrollen, sofern Sie diese Komponenten in AppScaffold und ScreenScaffold platzieren und den Listenstatus zwischen ScreenScaffold und der Komponente, z. B. einer TransformingLazyColumn, übergeben.

AppScaffold und ScreenScaffold bieten die grundlegende Layoutstruktur für Wear OS-Apps und haben bereits einen Steckplatz für einen Scrollindikator mit einer Standardimplementierung. Wenn Sie den Scrollvorgang anpassen möchten, erstellen Sie einen Scroll-Indikator basierend auf dem Listenstatusobjekt, wie im folgenden Code-Snippet gezeigt:

val listState = rememberTransformingLazyColumnState()
ScreenScaffold(
    scrollState = listState,
    scrollIndicator = {
        ScrollIndicator(state = listState)
    }
) {
    // ...
}

Sie können ein Anpassen-Verhalten für ScalingLazyColumn mit ScalingLazyColumnDefaults.snapFlingBehavior konfigurieren, wie im folgenden Code-Snippet gezeigt:

val listState = rememberScalingLazyListState()
ScreenScaffold(
    scrollState = listState,
    scrollIndicator = {
        ScrollIndicator(state = listState)
    }
) {

    val state = rememberScalingLazyListState()
    ScalingLazyColumn(
        modifier = Modifier.fillMaxWidth(),
        state = state,
        flingBehavior = ScalingLazyColumnDefaults.snapFlingBehavior(state = state)
    ) {
        // Content goes here
        // ...
    }
}

Benutzerdefinierte Aktionen

Sie können auch benutzerdefinierte Aktionen erstellen, die in Ihrer App auf die Drehknopf-Eingabe reagieren. So können Sie beispielsweise in einer Medien-App mit dem Drehknopf heran- und herauszoomen oder die Lautstärke regeln.

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 Rückruf, der zum Verarbeiten von Drehrad-Scrollereignissen 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 werden im vorherigen Beispiel Pixelwerte verwendet, die bei tatsächlicher Verwendung wahrscheinlich zu empfindlich sind.

Verwenden Sie den Callback, sobald Sie die Ereignisse erhalten haben, 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(),
) { ... }