Saat layanan aksesibilitas menavigasi elemen di layar, elemen-elemen ini harus dikelompokkan, dipisahkan, atau bahkan disembunyikan pada tingkat perincian yang tepat. Jika setiap satu composable level rendah di layar Anda disoroti secara independen, pengguna harus banyak berinteraksi untuk berpindah-pindah di layar. Jika elemen digabungkan dengan terlalu agresif, pengguna mungkin tidak memahami elemen mana yang secara logis menjadi satu. Jika ada elemen di layar yang murni dekoratif, elemen tersebut dapat disembunyikan dari layanan aksesibilitas. Dalam kasus ini, Anda dapat menggunakan Compose API untuk menggabungkan, menghapus, dan menyembunyikan semantik.
Semantik penggabungan
Saat Anda menerapkan pengubah clickable
ke composable induk, Compose
akan otomatis menggabungkan semua elemen turunan di bawahnya. Untuk memahami cara
komponen Compose Material dan Foundation interaktif menggunakan strategi penggabungan
secara default, lihat bagian Elemen interaktif.
Umumnya, komponen terdiri dari beberapa composable. Composable ini dapat membentuk grup yang logis dan masing-masing dapat berisi informasi penting, tetapi Anda mungkin tetap ingin layanan aksesibilitas melihatnya sebagai satu elemen.
Misalnya, bayangkan composable yang menampilkan avatar pengguna, nama mereka, dan beberapa informasi tambahan:

Anda dapat mengaktifkan Compose untuk menggabungkan elemen ini dengan menggunakan parameter mergeDescendants
dalam pengubah semantik. Dengan cara ini, layanan aksesibilitas memperlakukan
komponen sebagai satu entity, dan semua properti semantik turunan
digabungkan:
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
Layanan aksesibilitas kini berfokus pada seluruh penampung sekaligus, dan menggabungkan kontennya:

Setiap properti semantik memiliki strategi penggabungan yang ditetapkan. Misalnya, properti
ContentDescription
menambahkan semua nilai ContentDescription
turunan
ke daftar. Anda dapat memeriksa strategi penggabungan properti semantik dengan
memeriksa implementasi mergePolicy
-nya di SemanticsProperties.kt.
Properti dapat menggunakan nilai induk atau turunan, menggabungkan nilai ke dalam daftar
atau string, tidak mengizinkan penggabungan sama sekali dan menampilkan pengecualian, atau strategi penggabungan kustom lainnya.
Ada skenario lain saat Anda mengharapkan semantik turunan digabungkan ke dalam
semantik induk, tetapi hal itu tidak terjadi. Dalam contoh berikut, kita memiliki
induk item daftar clickable
dengan elemen turunan, dan kita mungkin mengharapkan
induk menggabungkan semuanya:

@Composable private fun ArticleListItem( openArticle: () -> Unit, addToBookmarks: () -> Unit, ) { Row(modifier = Modifier.clickable { openArticle() }) { // Merges with parent clickable: Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Article thumbnail" ) ArticleDetails() // Defies the merge due to its own clickable: BookmarkButton(onClick = addToBookmarks) } }
Saat pengguna menekan item clickable
Row
, artikel akan terbuka. Di dalam
lapisan bertingkat, terdapat BookmarkButton
untuk mem-bookmark artikel. Tombol bertingkat ini
muncul sebagai tidak digabungkan, sedangkan konten turunan lainnya di dalam baris
digabungkan:

Row
. Hierarki yang tidak digabungkan berisi node terpisah untuk setiap composable Text
.Beberapa composable tidak otomatis digabungkan di bawah induk, karena desainnya. Induk
tidak dapat menggabungkan turunannya saat turunan juga digabungkan, baik
dari setelan mergeDescendants = true
secara eksplisit maupun dengan menjadi komponen yang
menggabungkan dirinya sendiri, seperti tombol atau elemen yang dapat diklik. Mengetahui cara API tertentu menggabungkan atau menolak penggabungan dapat membantu Anda men-debug beberapa perilaku yang berpotensi tidak terduga.
Gunakan penggabungan saat elemen turunan membentuk grup yang logis dan masuk akal
di bawah induknya. Namun, jika turunan bertingkat memerlukan penyesuaian atau penghapusan semantiknya sendiri secara manual, API lain mungkin lebih sesuai dengan kebutuhan Anda (misalnya,
clearAndSetSemantics
).
Menghapus dan menetapkan semantik
Jika informasi semantik perlu dihapus atau ditimpa sepenuhnya, API yang efektif untuk digunakan adalah clearAndSetSemantics
.
Jika komponen memerlukan semantiknya sendiri dan turunannya dihapus, gunakan API ini dengan lambda kosong. Jika semantiknya harus ditimpa, sertakan konten baru Anda di dalam lambda.
Perhatikan bahwa saat menghapus dengan lambda kosong, semantik yang dihapus tidak
dikirim ke konsumen yang menggunakan informasi ini, seperti aksesibilitas, isi otomatis,
atau pengujian. Saat menimpa konten dengan
clearAndSetSemantics{/*semantic information*/}
, semantik baru akan menggantikan semua
semantik sebelumnya dari elemen dan turunannya.
Berikut adalah contoh komponen tombol khusus, yang direpresentasikan oleh baris yang dapat berinteraksi dengan ikon dan teks:
// Developer might intend this to be a toggleable. // Using `clearAndSetSemantics`, on the Row, a clickable modifier is applied, // a custom description is set, and a Role is applied. @Composable fun FavoriteToggle() { val checked = remember { mutableStateOf(true) } Row( modifier = Modifier .toggleable( value = checked.value, onValueChange = { checked.value = it } ) .clearAndSetSemantics { stateDescription = if (checked.value) "Favorited" else "Not favorited" toggleableState = ToggleableState(checked.value) role = Role.Switch }, ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null // not needed here ) Text("Favorite?") } }
Meskipun ikon dan teks memiliki beberapa informasi semantik, keduanya tidak menunjukkan bahwa komponen ini dapat diaktifkan/dinonaktifkan. Penggabungan tidak memadai karena Anda harus memberikan informasi tambahan tentang komponen.
Karena cuplikan di atas membuat komponen tombol khusus, Anda perlu menambahkan
kemampuan tombol, serta semantik stateDescription
,
toggleableState
, dan role
. Dengan cara ini, status komponen
dan tindakan terkait tersedia—misalnya, TalkBack mengumumkan
"Ketuk dua kali untuk beralih", bukan "Ketuk dua kali untuk mengaktifkan".
Dengan menghapus semantik asli dan menetapkan semantik baru yang lebih deskriptif, layanan aksesibilitas kini dapat melihat bahwa ini adalah komponen yang dapat diganti yang dapat mengubah status.
Saat menggunakan clearAndSetSemantics
, pertimbangkan hal berikut:
- Karena layanan tidak menerima informasi saat API ini ditetapkan, sebaiknya
gunakan seperlunya.
- Informasi semantik berpotensi dapat digunakan oleh agen AI dan layanan yang serupa untuk memahami layar, sehingga hanya boleh dihapus jika diperlukan.
- Semantik kustom dapat ditetapkan dalam lambda API.
- Urutan pengubah penting―API ini menghapus semua semantik yang ada setelah tempat penerapannya, terlepas dari strategi penggabungan lainnya.
Menyembunyikan semantik
Dalam beberapa skenario, elemen tidak perlu dikirim ke layanan aksesibilitas. Mungkin informasi tambahannya berlebihan untuk aksesibilitas, atau hanya dekoratif secara visual dan non-interaktif. Dalam hal ini, Anda
dapat menyembunyikan elemen dengan hideFromAccessibility
API.
Dalam contoh berikut adalah komponen yang mungkin perlu disembunyikan: watermark berlebihan yang membentang di komponen, dan karakter yang digunakan untuk memisahkan informasi secara dekoratif.
@Composable fun WatermarkExample( watermarkText: String, content: @Composable () -> Unit, ) { Box { WatermarkedContent() // Mark the watermark as hidden to accessibility services. WatermarkText( text = watermarkText, color = Color.Gray.copy(alpha = 0.5f), modifier = Modifier .align(Alignment.BottomEnd) .semantics { hideFromAccessibility() } ) } } @Composable fun DecorativeExample() { Text( modifier = Modifier.semantics { hideFromAccessibility() }, text = "A dot character that is used to decoratively separate information, like •" ) }
Penggunaan hideFromAccessibility
di sini memastikan watermark dan dekorasi
disembunyikan dari layanan aksesibilitas, tetapi tetap mempertahankan semantiknya untuk kasus
penggunaan lainnya, seperti pengujian.
Perincian kasus penggunaan
Berikut adalah ringkasan kasus penggunaan untuk memahami cara membedakan dengan jelas antara API sebelumnya:
- Jika konten tidak dimaksudkan untuk digunakan oleh layanan aksesibilitas:
- Gunakan
hideFromAccessibility
jika konten mungkin bersifat dekoratif atau redundan, tetapi masih harus diuji. - Gunakan
clearAndSetSemantics{}
dengan lambda kosong saat semantik induk dan turunan perlu dihapus untuk semua layanan. - Gunakan
clearAndSetSemantics{/*content*/}
dengan konten di dalam lambda saat semantik komponen perlu ditetapkan secara manual.
- Gunakan
- Jika konten harus diperlakukan sebagai satu entity, dan memerlukan semua informasi turunannya agar lengkap:
- Gunakan turunan semantik penggabungan.

Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Aksesibilitas di Compose
- [Desain Material 2 di Compose][19]
- Menguji tata letak Compose