Jika aplikasi Anda memerlukan komponen tampilan kustom, Anda harus membuat tampilan lebih mudah diakses. Langkah-langkah berikut dapat meningkatkan aksesibilitas tampilan kustom Anda, seperti yang dijelaskan di halaman ini:
- Menangani klik pengontrol arah.
- Mengimplementasikan metode API aksesibilitas.
- Mengirim objek
AccessibilityEvent
khusus untuk tampilan kustom Anda - Mengisi
AccessibilityEvent
danAccessibilityNodeInfo
untuk tampilan Anda
Menangani klik pengontrol arah
Pada sebagian besar perangkat, mengklik tampilan menggunakan pengontrol arah akan mengirimkan
KeyEvent
dengan
KEYCODE_DPAD_CENTER
ke tampilan yang saat ini menjadi fokus. Semua tampilan Android standar sudah menangani
KEYCODE_DPAD_CENTER
dengan tepat. Saat membuat kontrol
View
kustom, pastikan peristiwa ini memiliki efek yang sama dengan menyentuh tampilan di layar sentuh.
Kontrol kustom Anda harus memperlakukan peristiwa
KEYCODE_ENTER
sama dengan KEYCODE_DPAD_CENTER
. Dengan begitu, interaksi dengan keyboard
lengkap menjadi lebih mudah bagi pengguna.
Mengimplementasikan metode API aksesibilitas
Peristiwa aksesibilitas adalah pesan tentang interaksi pengguna dengan komponen antarmuka visual
aplikasi Anda. Pesan ini ditangani oleh layanan aksesibilitas, yang
menggunakan informasi dalam peristiwa ini untuk menghasilkan masukan dan perintah tambahan. Metode aksesibilitas
adalah bagian dari class View
dan
View.AccessibilityDelegate
. Metode tersebut adalah sebagai berikut:
dispatchPopulateAccessibilityEvent()
onPopulateAccessibilityEvent()
untuk tampilan ini,
lalu metode dispatchPopulateAccessibilityEvent()
untuk setiap turunan tampilan
ini. onInitializeAccessibilityEvent()
TextView
atau
Button
yang sederhana, ganti metode ini
dan tetapkan informasi tambahan tentang tampilan Anda—seperti jenis kolom sandi, jenis
kotak centang, atau status yang memberikan interaksi atau masukan kepada pengguna mengenai peristiwa tersebut—menggunakan metode
ini. Jika Anda mengganti metode ini, panggil implementasi supernya dan hanya ubah properti
yang tidak ditetapkan oleh class super.onInitializeAccessibilityNodeInfo()
View
default memiliki kumpulan standar properti tampilan. Namun, jika
tampilan kustom Anda memberikan kontrol interaktif di luar TextView
atau
Button
yang sederhana, Anda harus mengganti metode ini dan menetapkan informasi tambahan tentang tampilan
Anda ke objek AccessibilityNodeInfo
yang ditangani oleh metode ini.onPopulateAccessibilityEvent()
AccessibilityEvent
untuk tampilan
Anda. Ini juga dipanggil jika tampilan adalah turunan dari tampilan yang menghasilkan peristiwa
aksesibilitas.
onRequestSendAccessibilityEvent()
AccessibilityEvent
. Langkah ini memungkinkan tampilan induk mengubah peristiwa
aksesibilitas dengan informasi tambahan. Terapkan metode ini hanya jika tampilan kustom Anda dapat memiliki
tampilan turunan dan jika tampilan induk dapat memberikan informasi konteks ke peristiwa aksesibilitas
yang berguna untuk layanan aksesibilitas.sendAccessibilityEvent()
- Sistem memanggil metode ini saat pengguna mengambil tindakan pada tampilan. Peristiwa tersebut diklasifikasikan dengan
jenis tindakan pengguna seperti
TYPE_VIEW_CLICKED
. Secara umum, Anda harus mengirimAccessibilityEvent
kapan pun konten tampilan kustom Anda berubah. sendAccessibilityEventUnchecked()
- Metode ini digunakan ketika kode panggilan harus mengontrol secara langsung pemeriksaan
aksesibilitas yang diaktifkan pada perangkat
(
AccessibilityManager.isEnabled()
). Jika Anda mengimplementasikan metode ini, jalankan panggilan seolah-olah aksesibilitas diaktifkan, terlepas dari setelan sistemnya. Anda biasanya tidak perlu mengimplementasikan metode ini untuk tampilan kustom. dispatchPopulateAccessibilityEvent()
onInitializeAccessibilityEvent()
onInitializeAccessibilityNodeInfo()
onPopulateAccessibilityEvent()
TYPE_VIEW_CLICKED
TYPE_VIEW_FOCUSED
TYPE_VIEW_HOVER_ENTER
TYPE_VIEW_HOVER_EXIT
TYPE_VIEW_LONG_CLICKED
TYPE_VIEW_SCROLLED
- Menghasilkan
AccessibilityEvent
yang sesuai untuk tindakan klik yang diinterpretasikan. - Mengaktifkan layanan aksesibilitas untuk menjalankan tindakan klik kustom bagi pengguna yang tidak dapat menggunakan layar sentuh.
Untuk mendukung aksesibilitas, ganti dan implementasikan metode aksesibilitas sebelumnya secara langsung di class tampilan kustom Anda.
Setidaknya, implementasikan metode aksesibilitas berikut untuk class tampilan kustom Anda:
Untuk mengetahui informasi selengkapnya tentang mengimplementasikan metode tersebut, lihat bagian tentang mengisi peristiwa aksesibilitas.
Mengirim peristiwa aksesibilitas
Tergantung pada spesifikasi tampilan kustom, Anda mungkin perlu mengirim objek
AccessibilityEvent
pada waktu yang berbeda atau untuk peristiwa yang tidak ditangani oleh implementasi
default. Class View
akan memberikan implementasi default untuk jenis peristiwa
berikut:
Secara umum, Anda harus mengirim AccessibilityEvent
kapan pun konten tampilan kustom
Anda berubah. Misalnya, jika Anda menerapkan panel penggeser kustom yang memungkinkan pengguna memilih
nilai numerik dengan menekan tombol panah kiri atau kanan, tampilan kustom Anda harus memunculkan peristiwa
TYPE_VIEW_TEXT_CHANGED
setiap kali perubahan nilai penggeser. Contoh kode berikut menunjukkan penggunaan metode
sendAccessibilityEvent()
untuk melaporkan peristiwa ini.
Kotlin
override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return when(keyCode) { KeyEvent.KEYCODE_DPAD_LEFT -> { currentValue-- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) true } ... } }
Java
@Override public boolean onKeyUp (int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) { currentValue--; sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED); return true; } ... }
Mengisi peristiwa aksesibilitas
Setiap AccessibilityEvent
memiliki kumpulan properti yang diperlukan yang menggambarkan
status tampilan saat ini. Properti tersebut mencakup hal-hal seperti nama class, deskripsi
konten, dan status yang dicentang dari suatu tampilan. Properti khusus yang diperlukan untuk setiap jenis peristiwa dijelaskan
dalam
dokumentasi referensi
AccessibilityEvent
.
Implementasi View
akan memberikan nilai default untuk
properti tersebut. Banyak dari nilai tersebut, termasuk nama class dan stempel waktu peristiwa, disediakan
secara otomatis. Jika membuat komponen tampilan kustom, Anda harus memberikan beberapa informasi
tentang konten dan karakteristik tampilan. Informasi ini dapat menyederhanakan label
tombol dan dapat menyertakan informasi status tambahan yang ingin Anda tambahkan ke peristiwa.
Gunakan metode
onPopulateAccessibilityEvent()
dan
onInitializeAccessibilityEvent()
untuk mengisi atau mengubah informasi dalam AccessibilityEvent
. Gunakan
metode onPopulateAccessibilityEvent()
secara khusus untuk menambahkan atau mengubah konten
teks peristiwa, yang diubah menjadi perintah suara oleh layanan aksesibilitas seperti
TalkBack. Gunakan metode onInitializeAccessibilityEvent()
untuk mengisi informasi
tambahan tentang peristiwa, seperti status pemilihan tampilan.
Selain itu, implementasikan
metode
onInitializeAccessibilityNodeInfo()
. Layanan aksesibilitas menggunakan objek AccessibilityNodeInfo
yang diisi oleh metode
ini untuk menyelidiki hierarki tampilan yang menghasilkan peristiwa aksesibilitas setelah diterima
dan memberikan masukan yang sesuai kepada pengguna.
Contoh kode berikut menunjukkan cara mengganti ketiga metode ini dalam tampilan Anda:
Kotlin
override fun onPopulateAccessibilityEvent(event: AccessibilityEvent?) { super.onPopulateAccessibilityEvent(event) // Call the super implementation to populate its text for the // event. Then, add text not present in a super class. // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { event?.text?.add(text) } } override fun onInitializeAccessibilityEvent(event: AccessibilityEvent?) { super.onInitializeAccessibilityEvent(event) // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event?.isChecked = isChecked() } override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) { super.onInitializeAccessibilityNodeInfo(info) // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info?.isCheckable = true info?.isChecked = isChecked() // You typically only need to add the text for the custom view. if (text?.isNotEmpty() == true) { info?.text = text } }
Java
@Override public void onPopulateAccessibilityEvent(AccessibilityEvent event) { super.onPopulateAccessibilityEvent(event); // Call the super implementation to populate its text for the // event. Then, add the text not present in a super class. // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { event.getText().add(text); } } @Override public void onInitializeAccessibilityEvent(AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); // Call the super implementation to let super classes // set appropriate event properties. Then, add the new checked // property that is not supported by a super class. event.setChecked(isChecked()); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); // Call the super implementation to let super classes set // appropriate info properties. Then, add the checkable and checked // properties that are not supported by a super class. info.setCheckable(true); info.setChecked(isChecked()); // You typically only need to add the text for the custom view. CharSequence text = getText(); if (!TextUtils.isEmpty(text)) { info.setText(text); } }
Anda dapat mengimplementasikan metode ini secara langsung dalam class tampilan kustom.
Memberikan konteks aksesibilitas yang disesuaikan
Layanan aksesibilitas dapat memeriksa hierarki tampilan yang berisi komponen antarmuka pengguna yang menghasilkan peristiwa aksesibilitas. Hal ini memungkinkan layanan aksesibilitas memberikan informasi kontekstual yang lebih lengkap untuk membantu pengguna.
Ada kasus saat layanan aksesibilitas tidak bisa mendapatkan informasi yang memadai dari hierarki tampilan. Contoh hal ini adalah kontrol antarmuka kustom yang memiliki dua atau beberapa area yang dapat diklik secara terpisah, seperti kontrol kalender. Dalam hal ini, layanan tidak bisa mendapatkan informasi yang memadai karena subbagian yang dapat diklik bukan bagian dari hierarki tampilan.
Pada contoh di gambar 1, seluruh kalender diimplementasikan sebagai satu tampilan, sehingga layanan aksesibilitas tidak menerima cukup informasi tentang konten tampilan dan pilihan pengguna dalam tampilan kecuali jika developer menyediakan informasi tambahan. 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 mengumumkan "Kalender" atau "Kalender April", dan pengguna tidak tahu hari apa yang dipilih.
Untuk memberikan informasi konteks yang memadai bagi layanan aksesibilitas dalam situasi seperti ini, framework memberikan cara guna menentukan hierarki tampilan virtual. Hierarki tampilan virtual adalah cara bagi developer aplikasi untuk memberikan hierarki tampilan tambahan ke layanan aksesibilitas yang lebih cocok dengan informasi di layar. Pendekatan ini memungkinkan layanan aksesibilitas memberikan informasi konteks yang lebih berguna kepada pengguna.
Situasi lain ketika hierarki tampilan virtual mungkin diperlukan adalah antarmuka pengguna yang berisi
kumpulan kontrol View
yang memiliki beberapa fungsi yang terkait erat. Di sana, tindakan pada satu
kontrol akan memengaruhi konten dari satu atau beberapa elemen, seperti pemilih angka dengan tombol atas
dan bawah yang terpisah. Dalam hal ini, layanan aksesibilitas tidak bisa mendapatkan informasi yang memadai karena
tindakan pada satu kontrol akan mengubah konten di konten lain, dan hubungan kontrol tersebut mungkin
tidak terlihat layanan.
Untuk menangani situasi ini, kelompokkan kontrol terkait dengan tampilan yang memuatnya dan berikan hierarki tampilan virtual dari penampung ini untuk menggambarkan dengan jelas informasi dan perilaku yang diberikan oleh kontrol tersebut.
Agar dapat memberikan hierarki tampilan virtual untuk suatu tampilan, ganti metode
getAccessibilityNodeProvider()
dalam tampilan kustom Anda atau kelompok tampilan dan tampilkan implementasi
AccessibilityNodeProvider
.
Anda dapat mengimplementasikan hierarki tampilan virtual dengan menggunakan Support Library dengan metode
ViewCompat.getAccessibilityNodeProvider()
dan memberikan implementasi dengan
AccessibilityNodeProviderCompat
.
Untuk menyederhanakan tugas penyediaan informasi ke layanan aksesibilitas dan mengelola
fokus aksesibilitas, Anda dapat mengimplementasikan
ExploreByTouchHelper
.
Class ini menyediakan AccessibilityNodeProviderCompat
dan dapat dilampirkan sebagai AccessibilityDelegateCompat
tampilan dengan memanggil
setAccessibilityDelegate
.
Untuk contoh, lihat
ExploreByTouchHelperActivity
.
ExploreByTouchHelper
juga digunakan oleh widget framework seperti
CalendarView
, melalui
tampilan turunannya
SimpleMonthView
.
Menangani peristiwa sentuh kustom
Kontrol tampilan kustom mungkin memerlukan perilaku peristiwa sentuh non-standar, sebagaimana didemonstrasikan dalam contoh berikut.
Menentukan tindakan berbasis klik
Jika widget menggunakan
OnClickListener
atau
OnLongClickListener
antarmuka, sistem akan menangani
tindakan ACTION_CLICK
dan
ACTION_LONG_CLICK
untuk Anda. Jika aplikasi Anda menggunakan widget yang lebih disesuaikan yang mengandalkan
antarmuka OnTouchListener
,
tentukan pengendali kustom untuk tindakan aksesibilitas berbasis klik. Untuk melakukannya, panggil metode
replaceAccessibilityAction()
untuk setiap tindakan, sebagaimana ditunjukkan dalam cuplikan kode berikut:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { ... // Assumes that the widget is designed to select text when tapped, and selects // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select) ) { view, commandArguments -> selectText() } ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all) ) { view, commandArguments -> selectAllText() } }
Java
@Override protected void onCreate(Bundle savedInstanceState) { ... // Assumes that the widget is designed to select text when tapped, and select // all text when tapped and held. In its strings.xml file, this app sets // "select" to "Select" and "select_all" to "Select all". ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_CLICK, getString(R.string.select), (view, commandArguments) -> selectText()); ViewCompat.replaceAccessibilityAction( binding.textSelectWidget, ACTION_LONG_CLICK, getString(R.string.select_all), (view, commandArguments) -> selectAllText()); }
Membuat peristiwa klik kustom
Kontrol kustom dapat menggunakan metode pemroses onTouchEvent(MotionEvent)
untuk mendeteksi peristiwa
ACTION_DOWN
dan
ACTION_UP
serta
memicu peristiwa klik khusus. Untuk menjaga kompatibilitas dengan layanan aksesibilitas, kode yang menangani
peristiwa klik kustom ini harus melakukan hal berikut:
Untuk menangani persyaratan ini secara efisien, kode Anda harus mengganti
metode performClick()
,
yang harus memanggil implementasi super metode ini, lalu menjalankan tindakan apa pun
yang diperlukan oleh peristiwa klik. Saat tindakan klik kustom terdeteksi, kode tersebut kemudian akan memanggil
metode performClick()
Anda. Contoh kode berikut ini menunjukkan pola tersebut.
Kotlin
class CustomTouchView(context: Context) : View(context) { var downTouch = false override fun onTouchEvent(event: MotionEvent): Boolean { super.onTouchEvent(event) // Listening for the down and up touch events. return when (event.action) { MotionEvent.ACTION_DOWN -> { downTouch = true true } MotionEvent.ACTION_UP -> if (downTouch) { downTouch = false performClick() // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. true } else { false } else -> false // Return false for other touch events. } } override fun performClick(): Boolean { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick() // Handle the action for the custom click here. return true } }
Java
class CustomTouchView extends View { public CustomTouchView(Context context) { super(context); } boolean downTouch = false; @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); // Listening for the down and up touch events switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downTouch = true; return true; case MotionEvent.ACTION_UP: if (downTouch) { downTouch = false; performClick(); // Call this method to handle the response and // enable accessibility services to // perform this action for a user who can't // tap the touchscreen. return true; } } return false; // Return false for other touch events. } @Override public boolean performClick() { // Calls the super implementation, which generates an AccessibilityEvent // and calls the onClick() listener on the view, if any. super.performClick(); // Handle the action for the custom click here. return true; } }
Pola sebelumnya membantu memastikan bahwa peristiwa klik kustom kompatibel dengan layanan aksesibilitas
menggunakan metode performClick()
untuk membuat peristiwa aksesibilitas dan
menyediakan titik entri bagi layanan aksesibilitas untuk bertindak atas nama pengguna yang melakukan performa untuk peristiwa
klik kustom.