Input dari alat rotasi dengan Compose

Input dari alat rotasi mengacu pada input dari smartwatch yang berputar atau berotasi. Rata-rata, pengguna hanya menghabiskan beberapa detik untuk berinteraksi dengan smartwatch. Anda dapat meningkatkan pengalaman pengguna menggunakan input dari alat rotasi agar pengguna dapat menyelesaikan berbagai tugas dengan cepat.

Tiga sumber utama input dari alat rotasi pada sebagian besar smartwatch meliputi tombol samping yang berputar (RSB), dan bingkai fisik atau bingkai sentuh, yang merupakan zona sentuh melingkar di sekitar layar. Meskipun perilaku yang diharapkan dapat berbeda-beda berdasarkan jenis input, pastikan input dari alat rotasi untuk semua interaksi penting dapat didukung.

Scroll

Sebagian besar pengguna berharap aplikasi mendukung gestur scroll. Saat konten di-scroll di layar, berikan masukan visual kepada pengguna sebagai respons terhadap interaksi putar. Masukan visual dapat menyertakan indikator posisi untuk scroll vertikal atau indikator halaman.

ScalingLazyColumn dan Picker mendukung gestur scroll secara default, selama Anda perlu menempatkan komponen tersebut di dalam Scaffold. Scaffold menyediakan struktur tata letak dasar untuk aplikasi Wear OS dan telah dilengkapi slot untuk indikator scroll. Untuk menampilkan progres scroll, buat indikator posisi berdasarkan objek status daftar, seperti yang ditunjukkan dalam cuplikan kode berikut:

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

Anda dapat mengonfigurasi perilaku snap untuk ScalingLazyColumn menggunakan ScalingLazyColumnDefaults.snapFlingBehavior, seperti yang ditunjukkan dalam cuplikan kode berikut:

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

Tindakan kustom

Anda juga bisa membuat tindakan khusus yang merespons input dari alat rotasi di aplikasi Anda. Misalnya, gunakan input dari alat rotasi untuk memperbesar dan memperkecil atau mengontrol volume di aplikasi media.

Jika komponen Anda tidak mendukung peristiwa scroll seperti kontrol volume secara native, Anda dapat menangani peristiwa scroll sendiri.

// VolumeScreen.kt

val focusRequester: FocusRequester = remember { FocusRequester() }

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

Membuat status kustom yang dikelola di model tampilan, dan callback kustom yang digunakan untuk memproses peristiwa scroll putar.

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

Agar lebih praktis, contoh sebelumnya menggunakan nilai piksel yang jika benar-benar digunakan justru akan cenderung terlalu sensitif.

Gunakan callback setelah Anda menerima peristiwa, seperti yang ditunjukkan dalam cuplikan berikut.

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

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