Komposisi menjelaskan UI aplikasi Anda dan dihasilkan dengan menjalankan composable. Komposisi adalah struktur hierarki yang terdiri dari composable yang mendeskripsikan UI Anda.
Di samping Komposisi, ada pohon paralel yang disebut hierarki semantik. Hierarki ini menjelaskan UI dengan cara alternatif yang dapat dipahami untuk layanan Aksesibilitas dan untuk framework Pengujian. Layanan aksesibilitas menggunakan hierarki untuk mendeskripsikan aplikasi kepada pengguna dengan kebutuhan spesifik. Framework pengujian menggunakan hierarki untuk berinteraksi dengan aplikasi dan membuat pernyataan tentang aplikasi tersebut. Hierarki Semantik tidak berisi informasi cara menggambar composable, tetapi berisi informasi makna semantik composable Anda.
Jika aplikasi Anda terdiri atas composable dan pengubah dari library foundation dan material Compose, pohon Semantik akan otomatis diisi dan dibuat untuk Anda. Namun, saat menambahkan composable kustom tingkat rendah, 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:
Dalam contoh ini, seluruh kalender diimplementasikan sebagai satu composable tingkat rendah
menggunakan composable Layout
dan menggambar langsung ke Canvas
.
Jika Anda tidak melakukan tindakan lain, layanan aksesibilitas tidak akan menerima informasi
yang cukup 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, yang sedikit lebih baik, "Kalender April" dan pengguna
akan bertanya-tanya hari apa yang dipilih. Agar composable ini lebih mudah
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, composable
Text
berisi properti semantik text
karena itu adalah makna
dari composable tersebut. Icon
berisi properti contentDescription
(jika ditetapkan oleh
developer) yang menyampaikan makna Icon
dalam teks.
Composable dan pengubah yang di-build berdasarkan library
fondasi Compose sudah menetapkan properti yang relevan untuk Anda. Secara opsional, tetapkan
atau ganti properti Anda dengan pengubah semantics
dan
clearAndSetSemantics
. Misalnya, tambahkan tindakan aksesibilitas
kustom ke node, berikan deskripsi
status alternatif untuk elemen yang dapat diganti statusnya, atau tunjukkan bahwa composable teks
tertentu harus dianggap sebagai judul.
Untuk memvisualisasikan hierarki Semantik, gunakan Alat Layout Inspector atau gunakan metode
printToLog()
dalam pengujian. Tindakan ini akan mencetak pohon Semantik
saat ini 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:
Untuk mendeskripsikan makna elemen ini, Anda dapat mengucapkan: "Ini adalah Tombol Akses, yang merupakan elemen yang dapat diganti statusnya pada status 'Aktif'. Anda dapat mengkliknya untuk berinteraksi dengannya."
Inilah kegunaan properti semantik yang sebenarnya. Node semantik dari elemen Switch ini berisi properti berikut, seperti yang divisualisasikan dengan Layout Inspector:
Role
menunjukkan jenis elemen. StateDescription
menjelaskan cara
status "Aktif" direferensikan. Secara default, ini adalah versi lokal dari
kata "Aktif", tetapi dapat dibuat lebih spesifik (misalnya, "Diaktifkan") berdasarkan
konteksnya. ToggleableState
adalah status Tombol saat ini. Properti
OnClick
merujuk ke metode yang digunakan untuk berinteraksi dengan elemen ini. Untuk
mengetahui daftar lengkap properti semantik, lihat objek
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 secara lisan apa yang ditampilkan di layar dan memungkinkan pengguna berinteraksi dengannya secara lancar. Untuk composable Switch, Talkback mungkin akan bertuliskan: "Aktif; Switch; 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 dapat berupa:
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. Jika composable belum memiliki properti semantik yang ditetapkan, composable tersebut tidak akan 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. Dengan begitu, Anda dapat mempertimbangkan sekumpulan node secara keseluruhan, bukan menangani setiap node turunan satu per satu. Prinsipnya adalah, setiap node dalam pohon ini mewakili elemen yang dapat difokuskan selama menggunakan layanan Aksesibilitas.
Contoh composable tersebut adalah Button
. Anda dapat memikirkan 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") }
Dalam hierarki Semantik, properti turunan tombol digabungkan, dan tombol ditampilkan sebagai satu node daun dalam hierarki:
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
, composable
Button
menggunakan pengubah clickable
secara internal yang menyertakan
pengubah semantics
ini. Oleh karena itu, node turunan dari tombol digabungkan.
Baca dokumentasi aksesibilitas untuk mempelajari lebih lanjut kapan Anda harus mengubah perilaku
penggabungan dalam composable.
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 pohonnya
Hierarki semantik sebenarnya merupakan dua pohon yang berbeda. Ada pohon Semantik gabungan, yang menggabungkan node turunan saat mergeDescendants
ditetapkan ke true
.
Ada juga hierarki Semantik terpisah, yang tidak menerapkan penggabungan, tetapi
menjaga setiap node tetap utuh. Layanan aksesibilitas menggunakan hierarki yang terpisah dan menerapkan
algoritma penggabungannya sendiri, dengan mempertimbangkan properti
mergeDescendants
. Framework pengujian menggunakan hierarki gabungan secara default.
Anda dapat memeriksa kedua pohon tersebut menggunakan metode printToLog()
. Secara default, dan seperti pada contoh sebelumnya, pohon gabungan dicatat ke dalam log. Untuk mencetak hierarki yang terpisah, tetapkan parameter useUnmergedTree
dari pencocok onRoot()
ke
true
:
composeTestRule.onRoot(useUnmergedTree = true).printToLog("MY TAG")
Layout Inspector memungkinkan Anda menampilkan hierarki Semantik yang digabungkan dan terpisah, dengan memilih yang diinginkan dalam filter tampilan:
Untuk setiap node di pohon Anda, Layout Inspector akan menampilkan Semantik Gabungan dan Semantik yang ditetapkan di node tersebut dalam panel properti:
Secara default, pencocok dalam Framework Pengujian menggunakan pohon Semantik gabungan.
Itulah sebabnya Anda dapat berinteraksi dengan Button
dengan mencocokkan teks yang ditampilkan di dalamnya:
composeTestRule.onNodeWithText("Like").performClick()
Ganti perilaku ini dengan menetapkan parameter useUnmergedTree
matcher ke true
, seperti 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 mengambil nilai induk atau turunan, menggabungkan nilai ke dalam daftar atau string, tidak mengizinkan penggabungan sama sekali dan menampilkan pengecualian, atau strategi penggabungan khusus lainnya.
Catatan penting adalah bahwa turunan yang telah menetapkan mergeDescendants
= true
sendiri tidak disertakan dalam penggabungan. Lihat contoh berikut:
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 bertingkat yang dapat diklik, sehingga tombol tersebut muncul secara terpisah di hierarki gabungan. Konten lainnya yang ada di baris digabungkan:
Menyesuaikan hierarki Semantik
Seperti yang disebutkan sebelumnya, Anda dapat mengganti atau menghapus properti semantik tertentu atau mengubah perilaku penggabungan hierarki. Hal ini sangat relevan saat Anda membuat komponen kustom sendiri. Tanpa menetapkan properti dan perilaku penggabungan yang benar, aplikasi Anda mungkin tidak dapat diakses, dan pengujian mungkin akan berperilaku berbeda dari yang Anda harapkan. Untuk membaca selengkapnya tentang beberapa kasus penggunaan umum saat Anda harus menyesuaikan hierarki Semantik, baca dokumentasi aksesibilitas. Jika Anda ingin mempelajari pengujian lebih lanjut, lihat panduan pengujian.
Referensi tambahan
- Aksesibilitas: Konsep dan teknik penting yang umum untuk semua pengembangan aplikasi Android
- Membuat Aplikasi yang Mudah Diakses: Langkah-langkah utama yang dapat Anda lakukan untuk membuat aplikasi lebih mudah diakses
- Prinsip-prinsip untuk meningkatkan aksesibilitas aplikasi: Prinsip utama yang harus 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