Urutan traversal adalah urutan layanan aksesibilitas dalam menavigasi elemen UI. Dalam aplikasi Compose, elemen disusun dalam urutan pembacaan yang diharapkan, yang biasanya dari kiri ke kanan, lalu dari atas ke bawah. Namun, ada beberapa skenario saat Compose mungkin memerlukan petunjuk tambahan untuk menentukan urutan pembacaan yang benar.
isTraversalGroup dan traversalIndex adalah properti semantik yang
memungkinkan Anda memengaruhi urutan traversal untuk layanan aksesibilitas dalam skenario
saat algoritma pengurutan default Compose tidak memadai. isTraversalGroup
mengidentifikasi grup yang penting secara semantik yang memerlukan penyesuaian, sedangkan
traversalIndex menyesuaikan urutan setiap elemen dalam grup tersebut.
Anda dapat menggunakan isTraversalGroup saja untuk menandakan bahwa semua elemen dalam grup
harus dipilih bersama, atau dengan traversalIndex untuk penyesuaian lebih lanjut.
Gunakan isTraversalGroup dan traversalIndex di
aplikasi Anda untuk mengontrol urutan traversal pembaca layar.
Mengelompokkan elemen untuk penjelajahan
isTraversalGroup adalah properti boolean yang menentukan apakah node semantik
adalah grup traversal. Jenis node ini berfungsi sebagai batas dalam mengatur turunan node.
Menetapkan isTraversalGroup = true pada node berarti semua turunan node tersebut
akan dikunjungi sebelum berpindah ke elemen lain. Anda dapat menetapkan isTraversalGroup pada
node yang dapat difokuskan non-pembaca layar, seperti kolom, baris, atau kotak.
Contoh berikut menggunakan isTraversalGroup. Fungsi ini memunculkan empat elemen teks. Dua elemen di sebelah kiri termasuk dalam satu elemen CardBox, sedangkan dua elemen di sebelah kanan termasuk dalam elemen CardBox lainnya:
// CardBox() function takes in top and bottom sample text. @Composable fun CardBox( topSampleText: String, bottomSampleText: String, modifier: Modifier = Modifier ) { Box(modifier) { Column { Text(topSampleText) Text(bottomSampleText) } } } @Composable fun TraversalGroupDemo() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is " val bottomSampleText2 = "on the right." Row { CardBox( topSampleText1, bottomSampleText1 ) CardBox( topSampleText2, bottomSampleText2 ) } }
Kode tersebut menghasilkan output yang mirip dengan berikut ini:
Karena tidak ada semantik yang ditetapkan, perilaku default pembaca layar adalah melintasi elemen dari kiri ke kanan dan atas ke bawah. Karena setelan default ini, TalkBack membacakan fragmen kalimat dalam urutan yang salah:
"This sentence is in" → "This sentence is" → "the left column." → "di sebelah kanan".
Untuk mengurutkan fragmen dengan benar, ubah cuplikan asli untuk menetapkan
isTraversalGroup ke true:
@Composable fun TraversalGroupDemo2() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is" val bottomSampleText2 = "on the right." Row { CardBox( // 1, topSampleText1, bottomSampleText1, Modifier.semantics { isTraversalGroup = true } ) CardBox( // 2, topSampleText2, bottomSampleText2, Modifier.semantics { isTraversalGroup = true } ) } }
Karena isTraversalGroup ditetapkan secara khusus pada setiap CardBox, batas CardBox
berlaku saat mengurutkan elemennya. Dalam hal ini, CardBox kiri dibaca terlebih dahulu, diikuti dengan CardBox kanan.
Sekarang, TalkBack membacakan fragmen kalimat dalam urutan yang benar:
"Kalimat ini ada di" → "kolom kiri." → "Kalimat ini ada" → "di sebelah kanan".
Menyesuaikan urutan traversal
traversalIndex adalah properti float yang memungkinkan Anda menyesuaikan urutan traversal TalkBack. Jika pengelompokan elemen tidak cukup agar TalkBack
berfungsi dengan benar, gunakan traversalIndex bersama dengan
isTraversalGroup untuk menyesuaikan urutan pembaca layar lebih lanjut.
Properti traversalIndex memiliki karakteristik berikut:
- Elemen dengan nilai
traversalIndexyang lebih rendah akan diprioritaskan terlebih dahulu. - Dapat berupa nilai positif atau negatif.
- Nilai default-nya adalah
0f. - Agar indeks traversal memengaruhi perilaku traversal, indeks tersebut harus
ditetapkan pada komponen yang dapat dipilih dan difokuskan oleh layanan
aksesibilitas, seperti elemen di layar seperti teks atau tombol.
- Menetapkan hanya
traversalIndexpada, misalnya,Columntidak akan berpengaruh, kecuali jika kolom tersebut juga memilikiisTraversalGroupyang ditetapkan.
- Menetapkan hanya
Contoh berikut menunjukkan cara menggunakan traversalIndex dan
isTraversalGroup bersama-sama.
Tampilan jam adalah skenario umum saat pengurutan traversal standar tidak berfungsi. Contoh di bagian ini adalah pemilih waktu, tempat pengguna dapat melihat angka pada tampilan jam dan memilih digit untuk slot jam dan menit.
Dalam cuplikan yang disederhanakan berikut, ada CircularLayout yang menggambar 12
angka, dimulai dengan 12 dan bergerak searah jarum jam di sekeliling lingkaran:
@Composable fun ClockFaceDemo() { CircularLayout { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier) { Text((if (value == 0) 12 else value).toString()) } }
Karena tampilan jam tidak dibaca secara logis dengan urutan default dari kiri ke kanan dan dari atas ke bawah, TalkBack akan membacakan angka-angka tersebut secara tidak berurutan. Untuk memperbaikinya, gunakan nilai penghitung inkremental, seperti yang ditunjukkan dalam cuplikan berikut:
@Composable fun ClockFaceDemo() { CircularLayout(Modifier.semantics { isTraversalGroup = true }) { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) { Text((if (value == 0) 12 else value).toString()) } }
Untuk menetapkan urutan traversal dengan benar, jadikan CircularLayout sebagai
grup traversal terlebih dahulu dan tetapkan isTraversalGroup = true. Kemudian, saat setiap teks jam
digambar ke tata letak, tetapkan traversalIndex yang sesuai ke nilai
penghitung.
Karena nilai penghitung terus meningkat, traversalIndex setiap nilai jam
akan lebih besar seiring angka ditambahkan ke layar—nilai jam 0
memiliki traversalIndex 0, dan nilai jam 1 memiliki traversalIndex 1.
Dengan cara ini, urutan pembacaan TalkBack akan ditetapkan. Sekarang, angka
di dalam CircularLayout dibaca dalam urutan yang diharapkan.
Karena traversalIndexes yang telah ditetapkan hanya relatif terhadap indeks lain dalam pengelompokan yang sama, urutan layar lainnya tetap dipertahankan. Dengan kata lain, perubahan semantik yang ditampilkan dalam cuplikan kode sebelumnya
hanya mengubah pengurutan dalam tampilan jam yang telah
disetel isTraversalGroup = true.
Perhatikan bahwa, tanpa menyetel semantik CircularLayout's ke isTraversalGroup =
true, perubahan traversalIndex masih berlaku. Namun, tanpa
CircularLayout untuk mengikatnya, dua belas digit tampilan jam akan dibaca
terakhir, setelah semua elemen lain di layar dikunjungi. Hal ini terjadi
karena semua elemen lainnya memiliki traversalIndex default 0f, dan
elemen teks jam dibaca setelah semua elemen 0f lainnya.
Pertimbangan API
Pertimbangkan hal berikut saat menggunakan API traversal:
isTraversalGroup = trueharus ditetapkan pada induk yang berisi elemen yang dikelompokkan.traversalIndexharus ditetapkan pada komponen turunan yang berisi semantik dan akan dipilih oleh layanan aksesibilitas.- Pastikan semua elemen yang Anda selidiki berada pada tingkat
zIndexyang sama, karena hal ini juga memengaruhi semantik dan urutan traversal. - Pastikan tidak ada semantik yang digabungkan secara tidak perlu, karena hal ini dapat memengaruhi komponen yang menerapkan indeks traversal.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Aksesibilitas di Compose
- [Desain Material 2 di Compose][19]
- Menguji tata letak Compose Anda