Komposisi menjelaskan UI aplikasi Anda dan dihasilkan dengan menjalankan composable. Komposisinya adalah struktur pohon yang terdiri dari composable yang mendeskripsikan UI Anda.
Di samping Komposisi, terdapat pohon paralel yang disebut semantik hierarki. Pohon ini menjelaskan UI Anda dengan cara alternatif yang dimengerti untuk layanan Aksesibilitas dan untuk Pengujian Google Workspace for Education. Layanan aksesibilitas menggunakan hierarki untuk mendeskripsikan aplikasi kepada pengguna dengan kebutuhan tertentu. Framework pengujian menggunakan hierarki untuk berinteraksi dengan aplikasi Anda dan membuat pernyataan tentangnya. Hierarki Semantik tidak berisi informasi tentang cara menggambar composable, tetapi berisi informasi tentang makna semantik composable Anda.
![Hierarki UI standar dan pohon semantiknya](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-ui-tree.png?authuser=9&hl=id)
Jika aplikasi Anda terdiri atas composable dan pengubah dari library foundation dan material Compose, pohon Semantik akan otomatis diisi dan dibuat untuk Anda. Namun, ketika menambahkan composable tingkat rendah kustom, Anda harus menyediakan semantiknya secara manual. Mungkin juga ada situasi saat pohon Anda salah atau tidak sepenuhnya mewakili makna dari elemen di layar, dan Anda dapat menyesuaikan pohonnya.
Misalnya, perhatikan composable kalender kustom ini:
![Composable kalender kustom dengan elemen hari yang dapat dipilih](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-calendar.png?authuser=9&hl=id)
Dalam contoh ini, seluruh kalender diimplementasikan sebagai satu composable tingkat rendah
menggunakan composable Layout
dan menggambar langsung ke Canvas
.
Jika Anda tidak melakukan apa pun, layanan aksesibilitas tidak akan menerima
informasi tentang konten composable dan pilihan pengguna dalam
kalender. Misalnya, jika pengguna mengklik pada hari yang berisi 17,
framework aksesibilitas hanya akan menerima informasi
deskripsi untuk seluruh kontrol kalender. Dalam hal ini, layanan aksesibilitas TalkBack akan
mengumumkan "Kalender" atau, hanya sedikit lebih baik, "Kalender April" dan pengguna
akan bertanya-tanya hari apa yang dipilih. Untuk membuat composable ini lebih
dapat diakses, Anda harus menambahkan
informasi semantik secara manual.
Properti semantik
Semua node di pohon UI dengan beberapa makna semantik memiliki node paralel di
pohon Semantik. Node di pohon Semantik berisi properti yang
menyajikan makna composable yang sesuai. Misalnya, Text
composable berisi properti semantik text
, karena itulah makna dari
composable tersebut. Icon
berisi properti contentDescription
(jika ditetapkan oleh
developer) yang menyampaikan arti Icon
dalam teks.
Composable dan pengubah yang dibuat berdasarkan fondasi Compose
library telah menetapkan properti yang relevan untuk Anda. Secara opsional, atur
atau mengganti properti sendiri dengan semantics
dan
Pengubah clearAndSetSemantics
. Misalnya, tambahkan kustom
tindakan aksesibilitas ke node, memberikan status alternatif
deskripsi untuk elemen yang dapat diganti statusnya, atau menunjukkan bahwa teks tertentu
composable harus dianggap sebagai judul.
Untuk memvisualisasikan hierarki Semantik, gunakan Alat Layout Inspector atau gunakan
Metode printToLog()
di dalam pengujian. Ini akan mencetak nilai
Hierarki semantik di dalam Logcat.
class MyComposeTest { @get:Rule val composeTestRule = createComposeRule() @Test fun MyTest() { // Start the app composeTestRule.setContent { MyTheme { Text("Hello world!") } } // Log the full semantics tree composeTestRule.onRoot().printToLog("MY TAG") } }
Output pengujian ini adalah:
Printing with useUnmergedTree = 'false'
Node #1 at (l=0.0, t=63.0, r=221.0, b=120.0)px
|-Node #2 at (l=0.0, t=63.0, r=221.0, b=120.0)px
Text = '[Hello world!]'
Actions = [GetTextLayoutResult]
Pertimbangkan cara properti semantik menyampaikan arti composable. Pertimbangkan
Switch
. Ini yang akan dilihat pengguna:
![](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-switches.png?authuser=9&hl=id)
Untuk mendeskripsikan makna elemen ini, Anda dapat mengucapkan hal berikut: "This adalah {i>Switch<i}, yang merupakan elemen yang dapat dialihkan dalam tombol 'On' status. Anda dapat mengkliknya berinteraksi dengannya."
Inilah kegunaan properti semantik yang sebenarnya. Node semantik elemen Switch ini berisi properti berikut, seperti yang divisualisasikan dengan Layout Inspector:
![Layout Inspector menampilkan properti Semantik composable Switch](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-layout-inspector-switch.png?authuser=9&hl=id)
Role
menunjukkan jenis elemen. StateDescription
menjelaskan cara
"Aktif" harus direferensikan. Secara {i>default<i}, ini adalah
versi yang dilokalkan dari
kata "Aktif", tetapi Anda dapat membuatnya lebih spesifik (misalnya, "Diaktifkan") berdasarkan
berdasarkan konteks. ToggleableState
adalah status Tombol saat ini. Tujuan
Properti OnClick
mereferensikan metode yang digunakan untuk berinteraksi dengan elemen ini. Sebagai
daftar lengkap properti semantik, lihat SemanticsProperties
. Untuk daftar lengkap Tindakan Aksesibilitas yang mungkin, lihat objek
SemanticsActions
.
Melacak properti semantik dari setiap composable di aplikasi Anda akan membuka berbagai kemungkinan yang canggih. Beberapa contohnya:
- Talkback menggunakan properti untuk membacakan dengan lantang apa yang ditampilkan di layar dan memungkinkan pengguna berinteraksi dengan lancar. Untuk composable Switch, Talkback mungkin ucapkan: "Aktif; Beralih; ketuk dua kali untuk beralih". Pengguna dapat mengetuk dua kali layar untuk menonaktifkan Tombol.
-
Framework pengujian menggunakan properti untuk menemukan node, berinteraksi dengannya,
dan membuat pernyataan. Contoh pengujian untuk Tombol akses adalah:
val mySwitch = SemanticsMatcher.expectValue( SemanticsProperties.Role, Role.Switch ) composeTestRule.onNode(mySwitch) .performClick() .assertIsOff()
Pohon Semantik yang digabungkan dan yang tidak digabungkan
Seperti yang disebutkan sebelumnya, setiap composable di pohon UI mungkin memiliki nol atau beberapa properti semantik yang ditetapkan. Ketika composable belum menetapkan properti semantik, tidak disertakan sebagai bagian dari hierarki Semantik. Dengan demikian, pohon Semantik hanya berisi node yang benar-benar berisi makna semantik. Akan tetapi, terkadang menyampaikan makna yang benar dari informasi yang ditampilkan di layar juga berguna untuk menggabungkan sub-pohon tertentu dari node dan memperlakukannya sebagai node. Begitulah Anda dapat memikirkan tentang satu set {i>node<i} secara keseluruhan, daripada berurusan dengan masing-masing node turunan satu per satu. Prinsipnya adalah, setiap node dalam pohon ini mewakili elemen yang dapat difokuskan selama menggunakan layanan Aksesibilitas.
Contoh composable semacam ini adalah Button
. Anda dapat memberi alasan
tentang tombol
sebagai elemen tunggal, meskipun dapat berisi beberapa node turunan:
Button(onClick = { /*TODO*/ }) { Icon( imageVector = Icons.Filled.Favorite, contentDescription = null ) Spacer(Modifier.size(ButtonDefaults.IconSpacing)) Text("Like") }
Di hierarki Semantik, properti turunan tombol digabungkan, dan tombolnya ditampilkan sebagai node daun tunggal di hierarki:
![Penggabungan representasi semantik satu daun](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-merged-single-leaf.png?authuser=9&hl=id)
Composable dan pengubah dapat menunjukkan bahwa keduanya ingin menggabungkan
properti semantik turunannya dengan memanggil Modifier.semantics
(mergeDescendants = true) {}
. Menyetel properti ini ke true
menunjukkan bahwa
properti semantik harus digabungkan. Dalam contoh Button
, Button
composable menggunakan pengubah clickable
secara internal yang menyertakan
Pengubah semantics
. Oleh karena itu, node turunan tombol digabungkan.
Baca dokumentasi aksesibilitas untuk mempelajari lebih lanjut kapan Anda harus mengubah
menggabungkan perilaku di composable Anda.
Beberapa pengubah dan composable di library Foundation dan
Material Compose memiliki kumpulan properti ini. Misalnya, pengubah clickable
dan toggleable
akan otomatis menggabungkan turunannya. Selain itu, composable
ListItem
akan menggabungkan turunannya.
Periksa hierarki
Pohon semantik sebenarnya adalah dua pohon yang berbeda. Ada Semantik digabungkan
pohon, yang menggabungkan node turunan saat mergeDescendants
ditetapkan ke true
.
Ada juga hierarki Semantik yang terpisah, yang tidak menerapkan penggabungan, tetapi
menjaga setiap {i>node<i} tetap utuh. Layanan aksesibilitas menggunakan hierarki yang terpisah dan menerapkannya
algoritma penggabungannya sendiri, dengan mempertimbangkan mergeDescendants
saat ini. Framework pengujian secara default menggunakan hierarki gabungan.
Anda dapat memeriksa kedua pohon tersebut menggunakan metode printToLog()
. Secara {i>default<i}, seperti pada
contoh sebelumnya, pohon yang digabungkan akan dicatat. Untuk mencetak pohon yang dipisahkan
sebagai gantinya, tetapkan parameter useUnmergedTree
dari pencocok onRoot()
ke
true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("MY TAG")
Layout Inspector memungkinkan Anda menampilkan Semantik yang digabungkan dan yang tidak digabungkan hierarki, dengan memilih yang diinginkan pada filter tampilan:
![Opsi tampilan Layout Inspector, yang memungkinkan tampilan hierarki Semantik yang digabungkan dan terpisah](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-layout-inspector-menu.png?authuser=9&hl=id)
Untuk setiap node di pohon Anda, Layout Inspector akan menampilkan Semantik Gabungan dan Semantik yang ditetapkan di node tersebut dalam panel properti:
![Properti semantik digabungkan dan ditetapkan](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-merged-and-set.png?authuser=9&hl=id)
Secara default, pencocok dalam Framework Pengujian menggunakan pohon Semantik gabungan.
Itulah sebabnya Anda dapat berinteraksi dengan Button
dengan mencocokkan teks yang ditampilkan di dalamnya
hal tersebut:
composeTestRule.onNodeWithText("Like").performClick()
Ganti perilaku ini dengan menyetel parameter useUnmergedTree
dari
pencocok untuk true
, seperti dengan pencocok onRoot
.
Perilaku penggabungan
Saat composable menunjukkan bahwa turunannya harus digabungkan, bagaimana penggabungan ini sebenarnya dilakukan?
Setiap properti semantik memiliki strategi penggabungan yang ditetapkan. Misalnya,
Properti ContentDescription
menambahkan semua nilai ContentDescription turunan ke
daftar. Periksa strategi penggabungan properti semantik dengan memeriksa
Implementasi mergePolicy
di SemanticsProperties.kt
. Properti dapat
menggunakan nilai induk atau turunan, menggabungkan nilai-nilai tersebut ke dalam daftar atau
{i>string<i}, tidak memungkinkan penggabungan sama sekali dan melemparkan pengecualian sebagai gantinya, atau
strategi penggabungan kustom.
Catatan penting adalah bahwa turunan yang telah menetapkan mergeDescendants
= true
tidak akan disertakan dalam penggabungan. Lihat contoh berikut:
![Item daftar dengan gambar, beberapa teks, dan ikon bookmark](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-dagger.png?authuser=9&hl=id)
Berikut adalah item daftar yang dapat diklik. Saat pengguna menekan baris, aplikasi akan membuka halaman detail artikel, tempat pengguna dapat membaca artikel. Di dalam item daftar, terdapat tombol untuk mem-bookmark artikel, yang membentuk elemen yang dapat diklik bertingkat, sehingga tombol muncul secara terpisah dalam pohon yang digabungkan. Konten lainnya yang ada di baris digabungkan:
![Pohon gabungan berisi beberapa teks dalam daftar di dalam node Baris. Pohon terpisah berisi node yang terpisah untuk setiap komposisi Teks.](https://developer.android.google.cn/static/develop/ui/compose/images/semantics-merged-vs-unmerged.png?authuser=9&hl=id)
Menyesuaikan hierarki Semantik
Seperti yang disebutkan sebelumnya, Anda dapat mengganti atau menghapus properti semantik tertentu, atau mengubah perilaku penggabungan pohon. Hal ini sangat relevan ketika Anda membuat komponen kustom sendiri. Tanpa menetapkan dan perilaku penggabungan, aplikasi Anda mungkin tidak dapat diakses, dan pengujian mungkin berperilaku berbeda dari yang Anda harapkan. Untuk membaca lebih lanjut beberapa kasus penggunaan umum di mana Anda harus menyesuaikan hierarki Semantik, baca aksesibilitas dokumentasi tambahan. Jika Anda ingin mempelajari lebih lanjut pengujian, lihat pengujian panduan kami.
Referensi lainnya
- Aksesibilitas: Konsep dan teknik yang umum untuk semua pengembangan aplikasi Android
- Membuat Aplikasi yang Dapat Diakses: Langkah-langkah penting yang dapat dilakukan untuk membuat aplikasi Anda lebih mudah diakses
- Prinsip-prinsip untuk meningkatkan kualitas aplikasi aksesibilitas: Prinsip utama untuk perlu diingat saat berupaya membuat aplikasi Anda lebih mudah diakses
- Menguji Aksesibilitas: Prinsip dan alat pengujian untuk aksesibilitas Android
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Aksesibilitas di Compose
- Desain Material 2 di Compose
- Menguji tata letak Compose