Di Wear OS 7 (level API 37) dan yang lebih tinggi, framework gestur satu tangan, beserta API yang merupakan bagian dari Compose untuk Wear OS, memungkinkan pengguna berinteraksi dengan aplikasi Anda tanpa sentuhan.
Meskipun awalnya didukung di perangkat Pixel Watch (Pixel Watch 3 dan yang lebih baru), framework ini tersedia untuk semua OEM. Dengan mengadopsi API ini, dukungan gestur aplikasi Anda akan otomatis diskalakan di seluruh ekosistem seiring dengan perluasan dukungan hardware.
Untuk membantu pengguna menemukan gestur yang tersedia tanpa membuat UI berantakan, framework Wear OS menyediakan indikator gestur animasi. Petunjuk visual ini menyoroti tempat gestur dapat dilakukan, sementara sistem secara otomatis mengelola irama tampilan dan frekuensi peredamannya sesuai dengan preferensi pengguna.
Gestur dan tindakan yang didukung
Framework gestur Wear OS mendukung dua jenis gestur:
- Tindakan utama (Mencubit dua jari): Memetakan ke tindakan utama di layar, seperti menjawab panggilan atau mengalihkan pemutaran media.
- Tindakan tutup (Putar pergelangan tangan): Memetakan ke navigasi mundur, menutup dialog, atau membatalkan perintah.
Mengonfigurasi gestur di Compose
Meskipun API gestur satu tangan dapat meningkatkan kualitas UI Anda, penting untuk diingat bahwa beberapa hardware dan OEM tidak mendukung gestur ini. Jika API mendeteksi bahwa aplikasi Anda berjalan di salah satu perangkat yang tidak didukung ini, library akan otomatis melakukan no-op tanpa memengaruhi interaksi sentuh standar.
Seperti perilaku Compose standar, Anda dapat mengaktifkan gestur satu tangan pada elemen
UI menggunakan pengubah. Anda mengonfigurasi gestur aplikasi
sesuai dengan tindakan yang akan dilakukan—baik utama maupun tutup—dan gestureId
untuk berkoordinasi dengan preferensi pengguna tingkat sistem, seperti irama tampilan saran
dan peredaman frekuensi. Anda menyatakan konfigurasi ini dengan membuat objek
OneHandedGestureConfiguration; sebaiknya gunakan fungsi
rememberOneHandedGestureConfiguration untuk membuatnya. OneHandedGestureConfiguration
juga merupakan tempat Anda dapat memberikan prioritas
gestur.
Fungsi rememberOneHandedGestureConfiguration melacak histori interaksi pengguna di seluruh rekomposisi tanpa mengekspos status aplikasi. Setelah aplikasi Anda membuat konfigurasi, aplikasi tersebut harus meneruskan konfigurasi ke
Modifier.oneHandedGesture pada composable interaktif Anda.
Untuk membantu pengguna menemukan gestur yang tersedia, library menyediakan metode
OneHandedGestureClickIndicator. Metode ini berfungsi sebagai wrapper yang
menggantikan konten dasarnya untuk menunjukkan kepada pengguna bahwa tindakan gestur
tersedia.
Komponen interaktif
Untuk mengaktifkan gestur pada kontrol interaktif seperti tombol, buat konfigurasi yang menentukan OneHandedGestureAction.Primary dan terapkan pengubah oneHandedGesture. Teruskan MutableInteractionSource yang sama ke
kontrol dan pengubah sehingga peristiwa gestur memancarkan masukan tekanan visual ke
kontrol.
Untuk mengaktifkan indikator gestur, buat dan ingat instance
OneHandedGestureClickIndicatorState. Kemudian, untuk memicu masukan visual, panggil showIndicator dalam callback onGestureAvailable yang disediakan oleh pengubah oneHandedGesture, yang memberi sinyal kepada sistem bahwa peristiwa indikasi telah terjadi. Setelah dipanggil, komponen akan mengganti konten
normalnya dengan animasi gestur untuk sementara.
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()) } }
Penampung yang dapat di-scroll
Untuk layar atau daftar yang dapat di-scroll, buat konfigurasi yang menentukan
OneHandedGestureAction.Primary dan terapkan pengubah oneHandedGesture ke
penampung Anda, dengan memanggil helper scrolling seperti scrollDown.
Untuk memberikan masukan visual untuk tindakan men-scroll, Anda dapat menggunakan
OneHandedGestureScrollIndicator. Komponen ini berfungsi
sebagai indikator scroll standar yang menunjukkan posisi scroll, tetapi juga dapat
menunjukkan bahwa gestur scroll tersedia untuk pengguna. Indikator ini biasanya diteruskan ke slot scrollIndicator dari
ScreenScaffold dan digabungkan dengan status
penampung yang dapat di-scroll, seperti TransformingLazyColumn. ini juga mengamati
OneHandedGestureScrollIndicatorState untuk mengelola transisi visualnya.
Untuk memicu masukan visual, panggil showIndicator pada status ini—biasanya
di dalam callback onGestureAvailable dari pengubah oneHandedGesture.
Setelah dipicu, indikator akan menggantikan status visual standarnya untuk sementara dengan urutan animasi gestur guna memberi tahu pengguna.
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)) } } }
Menggabungkan beberapa gestur
Anda dapat mengonfigurasi gestur scroll dan gestur klik dengan
tindakan utama yang sama dengan menambahkan gesturePriority ke objek
OneHandedGestureConfiguration:
OneHandedGesturePriority.Clickable(tertinggi): Tetapkan ke kontrol interaktif—seperti yang memiliki jenisButtonatauCard—sehingga kontrol tersebut dapat merekam gestur saat terlihat di layar.OneHandedGesturePriority.Scrollable(sedang): Tetapkan ke penampung yang dapat di-scroll atau di-page sehingga elemen tersebut tunduk pada turunan yang dapat diklik, tetapi di-scroll saat tidak ada kontrol yang dapat diklik yang terlihat.OneHandedGesturePriority.Unspecified(terendah): Prioritas yang belum ditetapkan. Ini adalah nilai default untuk gestur yang tidak memiliki setelanpriority.
Dengan menetapkan priority = OneHandedGesturePriority.Clickable
secara eksplisit pada tombol dalam dan priority = OneHandedGesturePriority.Scrollable
pada daftar induknya, sistem dapat menampilkan perilaku prioritas gestur ini.
Saat pengguna memicu tindakan utama dengan gestur satu tangan, tindakan tersebut
pertama-tama akan men-scroll daftar ke bawah hingga tombol terlihat, lalu
merekam tindakan klik tombol.
Menguji dan men-debug gestur dengan ADB
Anda dapat menguji gestur satu tangan di perangkat fisik atau emulator tanpa melakukan gerakan pergelangan tangan fisik menggunakan Android Debug Bridge (adb) dan layanan sistem IWearGestureService.
Mengaktifkan simulasi gestur
Sebelum menyimulasikan gestur menggunakan ADB, konfigurasi setelan perangkat dan penggantian batasan:
Verifikasi bahwa perangkat Wear OS Anda menjalankan Wear OS 7 (level API 37) dan yang lebih tinggi:
adb shell getprop ro.build.version.sdkJika Anda melakukan pengujian di perangkat fisik yang tidak terpasang di pergelangan tangan atau sedang diisi daya, ganti batasan di luar tubuh agar framework gestur tetap aktif:
adb shell cmd IWearGestureService override-constraints offbody-state
Memicu peristiwa gestur menggunakan ADB
Untuk menyimulasikan gestur cubit dua kali (yang merupakan tindakan Primary di smartwatch Pixel), jalankan perintah shell ADB berikut:
adb shell cmd IWearGestureService gesture DoublePinch
Untuk menyimulasikan gestur Putar pergelangan tangan (yang merupakan tindakan Dismiss di smartwatch Pixel), jalankan perintah shell ADB berikut:
adb shell cmd IWearGestureService gesture WristTurn
Mereset pelacakan petunjuk gestur
Sistem melacak histori interaksi pengguna dan menampilkan petunjuk gestur mengambang berdasarkan setelan irama global (seperti Selalu atau Harian). Saat men-debug indikator gestur aplikasi, reset histori pelacakan ini agar petunjuk muncul lagi untuk paket Anda:
Pada build atau emulator
userdebug:adb shell cmd IWearGestureService hint clear <your_package_name>Pada build retail (
user):Di perangkat komersial tanpa akses root,
hint cleardiblokir oleh izin sistem. Hapus data lokal aplikasi untuk mereset penemuan saran:adb shell pm clear <your_package_name>
Memulihkan batasan default
Untuk mereset semua penggantian batasan debug setelah Anda selesai menguji:
adb shell cmd IWearGestureService override-constraints reset
Memecahkan masalah injeksi gestur
Jika aplikasi Anda tidak menerima gestur simulasi:
Pastikan layar smartwatch aktif dan DINYALAKAN. Framework gestur tidak mengirimkan gestur ke aplikasi saat layar mati atau dalam mode standby. Untuk mengaktifkan layar menggunakan ADB, jalankan:
adb shell input keyevent KEYCODE_WAKEUPPeriksa apakah aplikasi Anda terdaftar sebagai pelanggan gestur aktif dan saat ini memegang fokus jendela:
adb shell cmd IWearGestureService get-active-gestures -readableSaat layar gestur aplikasi Anda berada di latar depan dan layar aktif, perintah ini akan menampilkan
[DoublePinch]atau[DoublePinch, WristTurn]. Jika daftar kosong ([]) ditampilkan, periksa apakah jendela Anda memiliki fokus atau apakah batasan di luar tubuh menghalangi aktivasi.Periksa status layanan gestur internal dan token pelanggan aktif:
adb shell dumpsys IWearGestureService
Referensi lainnya
Untuk panduan desain tentang kapan dan di mana menggunakan gestur satu tangan, lihat Gestur satu tangan.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Panduan desain gestur satu tangan