Поворотный ввод с помощью Compose

Вращающийся ввод относится к вводу данных с частей ваших часов, которые вращаются или вращаются. В среднем пользователи тратят всего несколько секунд на взаимодействие со своими часами. Вы можете улучшить взаимодействие с пользователем, используя поворотный ввод, позволяющий пользователю быстро выполнять различные задачи.

Три основных источника поворотного ввода на большинстве часов включают вращающуюся боковую кнопку (RSB) и либо физическую лицевую панель, либо сенсорную панель, которая представляет собой круглую сенсорную зону вокруг экрана. Хотя ожидаемое поведение может различаться в зависимости от типа ввода, обязательно поддерживайте поворотный ввод для всех основных взаимодействий.

Прокрутка

Большинство пользователей ожидают, что приложения будут поддерживать жест прокрутки. По мере прокрутки контента на экране предоставляйте пользователям визуальную обратную связь в ответ на поворотные взаимодействия. Визуальная обратная связь может включать индикаторы положения вертикальной прокрутки или индикаторы страниц .

ScalingLazyColumn и Picker по умолчанию поддерживают жест прокрутки, если вам нужно поместить эти компоненты внутри Scaffold . Scaffold предоставляет базовую структуру макета для приложений Wear OS и уже имеет слот для индикатора прокрутки. Чтобы показать ход прокрутки, создайте индикатор положения на основе объекта состояния списка, как показано в следующем фрагменте кода:

val listState = rememberScalingLazyListState()
Scaffold(
    positionIndicator = {
        PositionIndicator(scalingLazyListState = listState)
    }
) {
    // ...
}

Вы можете настроить поведение привязки для ScalingLazyColumn с помощью ScalingLazyColumnDefaults.snapFlingBehavior , как показано в следующем фрагменте кода:

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

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

Пользовательские действия

Вы также можете создавать собственные действия, которые реагируют на поворотный ввод в вашем приложении. Например, используйте поворотный ввод для увеличения и уменьшения масштаба или для управления громкостью в мультимедийном приложении.

Если ваш компонент изначально не поддерживает события прокрутки, такие как регулировка громкости, вы можете обрабатывать события прокрутки самостоятельно.

// VolumeScreen.kt

val focusRequester: FocusRequester = remember { FocusRequester() }

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

Создайте собственное состояние, управляемое в модели представления, и настраиваемый обратный вызов, который будет использоваться для обработки событий поворотной прокрутки.

// 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)
    }
}

Для простоты в предыдущем примере используются значения пикселей, которые, если их действительно использовать, вероятно, будут слишком чувствительными.

Используйте обратный вызов после получения событий, как показано в следующем фрагменте.

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

Column(
    modifier = Modifier
        .fillMaxSize()
        .onRotaryScrollEvent {
            volumeViewModel
                .onVolumeChangeByScroll(it.verticalScrollPixels)
            true
        }
        .focusRequester(focusRequester)
        .focusable(),
) { ... }
{% дословно %} {% дословно %} {% дословно %} {% дословно %}