Prinsip-prinsip untuk meningkatkan aksesibilitas aplikasi

Untuk membantu pengguna dengan kebutuhan aksesibilitas, framework Android memungkinkan Anda membuat layanan aksesibilitas yang dapat menyajikan konten dari aplikasi kepada pengguna dan juga mengoperasikan aplikasi atas nama mereka.

Android menyediakan beberapa layanan aksesibilitas sistem, termasuk:

  • TalkBack: membantu pengguna yang memiliki gangguan penglihatan atau tunanetra. Fitur ini mengumumkan konten melalui suara yang disintesis dan melakukan tindakan di aplikasi sebagai respons terhadap gestur pengguna.
  • Tombol Akses: membantu penyandang disabilitas motorik. Fitur ini menyoroti elemen interaktif dan melakukan tindakan sebagai respons terhadap pengguna yang menekan tombol. Mode ini memungkinkan mengontrol perangkat hanya dengan menggunakan satu atau dua tombol.

Untuk membantu orang yang memerlukan aksesibilitas agar berhasil menggunakan aplikasi Anda, aplikasi Anda harus mengikuti praktik terbaik yang dijelaskan di halaman ini, yang dibuat berdasarkan pedoman yang dijelaskan dalam Membuat aplikasi lebih mudah diakses.

Setiap praktik terbaik ini, yang dijelaskan di bagian berikut, dapat semakin meningkatkan aksesibilitas aplikasi Anda:

Elemen label
Pengguna harus dapat memahami konten dan tujuan setiap elemen UI yang interaktif dan bermakna dalam aplikasi Anda.
Menambahkan tindakan aksesibilitas
Dengan menambahkan tindakan aksesibilitas, Anda dapat memungkinkan pengguna layanan aksesibilitas menyelesaikan alur penggunaan penting dalam aplikasi Anda.
Memperluas widget sistem
Buat elemen tampilan yang disertakan oleh framework, bukan membuat tampilan kustom Anda sendiri. Class tampilan dan widget framework sudah menyediakan sebagian besar kemampuan aksesibilitas yang dibutuhkan aplikasi Anda.
Menggunakan isyarat selain warna
Pengguna harus dapat membedakan kategori elemen di UI dengan jelas. Untuk melakukannya, gunakan pola dan posisi serta warna untuk menunjukkan perbedaannya.
Menjadikan konten media lebih mudah diakses
Tambahkan deskripsi pada konten video atau audio aplikasi Anda, sehingga pengguna yang menikmati konten ini tidak perlu sepenuhnya mengandalkan petunjuk visual atau aural.

Elemen label

Penting untuk menyediakan label yang deskriptif dan berguna kepada pengguna untuk setiap elemen UI interaktif di aplikasi Anda. Setiap label harus menjelaskan arti dan tujuan elemen tertentu. Pembaca layar seperti TalkBack dapat membacakan label ini kepada pengguna.

Pada umumnya, Anda menentukan deskripsi elemen UI dalam file resource tata letak yang berisi elemen. Biasanya, Anda akan menambahkan label menggunakan atribut contentDescription, seperti yang dijelaskan dalam panduan untuk membuat aplikasi lebih mudah diakses. Ada beberapa teknik pelabelan lain yang dijelaskan di bagian berikut.

Elemen yang dapat diedit

Saat melabeli elemen yang dapat diedit, seperti objek EditText, sebaiknya tampilkan teks yang memberikan contoh input yang valid dalam elemen itu sendiri, selain membuat teks contoh ini tersedia bagi pembaca layar. Dalam situasi ini, Anda dapat menggunakan atribut android:hint, seperti ditunjukkan dalam cuplikan berikut:

<!-- The hint text for en-US locale would be
     "Apartment, suite, or building". -->
<EditText
   android:id="@+id/addressLine2"
   android:hint="@string/aptSuiteBuilding" ... />

Dalam situasi ini, objek View harus memiliki atribut android:labelFor yang ditetapkan ke ID elemen EditText. Untuk detail selengkapnya, lihat bagian berikut.

Menyambungkan elemen yang salah satunya mendeskripsikan elemen lainnya

Sangatlah umum bagi elemen EditText untuk memiliki objek View yang sesuai, yang menjelaskan apa yang harus dimasukkan pengguna dalam elemen EditText. Anda dapat menunjukkan hubungan ini dengan menyetel atribut android:labelFor objek View.

Contoh pelabelan untuk pasangan elemen tersebut ditunjukkan pada cuplikan berikut:


<!-- Label text for en-US locale would be "Username:" -->
<TextView
   android:id="@+id/usernameLabel" ...
   android:text="@string/username"
   android:labelFor="@+id/usernameEntry" />

<EditText
   android:id="@+id/usernameEntry" ... />

<!-- Label text for en-US locale would be "Password:" -->
<TextView
   android:id="@+id/passwordLabel" ...
   android:text="@string/password
   android:labelFor="@+id/passwordEntry" />

<EditText
   android:id="@+id/passwordEntry"
   android:inputType="textPassword" ... />

Elemen dalam koleksi

Saat menambahkan label ke elemen koleksi, setiap label harus unik. Dengan cara ini, layanan aksesibilitas sistem dapat merujuk dengan tepat ke satu elemen di layar saat membacakan label. Hubungan ini memungkinkan pengguna mengetahui kapan mereka melakukan siklus UI atau kapan mereka memindahkan fokus ke elemen yang telah ditemukan.

Secara khusus, sertakan teks tambahan atau informasi kontekstual di elemen dalam tata letak yang digunakan kembali—seperti objek RecyclerView—sehingga setiap elemen turunan diidentifikasi secara unik.

Untuk melakukannya, setel deskripsi konten sebagai bagian dari implementasi adaptor Anda, seperti ditunjukkan dalam cuplikan kode berikut:

Kotlin

data class MovieRating(val title: String, val starRating: Integer)

class MyMovieRatingsAdapter(private val myData: Array<MovieRating>):
        RecyclerView.Adapter<MyMovieRatingsAdapter.MyRatingViewHolder>() {

    class MyRatingViewHolder(val ratingView: ImageView) :
            RecyclerView.ViewHolder(ratingView)

    override fun onBindViewHolder(holder: MyRatingViewHolder, position: Int) {
        val ratingData = myData[position]
        holder.ratingView.contentDescription = "Movie ${position}: " +
                "${ratingData.title}, ${ratingData.starRating} stars"
    }
}

Java

public class MovieRating {
    private String title;
    private int starRating;
    // ...
    public String getTitle() { return title; }
    public int getStarRating() { return starRating; }
}

public class MyMovieRatingsAdapter
        extends RecyclerView.Adapter<MyAdapter.MyRatingViewHolder> {
    private MovieRating[] myData;


    public static class MyRatingViewHolder extends RecyclerView.ViewHolder {
        public ImageView ratingView;
        public MyRatingViewHolder(ImageView iv) {
            super(iv);
            ratingView = iv;
        }
    }

    @Override
    public void onBindViewHolder(MyRatingViewHolder holder, int position) {
        MovieRating ratingData = myData[position];
        holder.ratingView.setContentDescription("Movie " + position + ": " +
                ratingData.getTitle() + ", " + ratingData.getStarRating() +
                " stars")
    }
}

Grup konten terkait

Jika aplikasi Anda menampilkan beberapa elemen UI yang membentuk grup secara otomatis, seperti detail lagu atau atribut pesan, atur elemen tersebut dalam penampung, yang umumnya merupakan subclass ViewGroup. Setel atribut android:screenReaderFocusable objek container ke true, dan setiap atribut android:focusable objek inti ke false. Dengan cara ini, layanan aksesibilitas dapat menyajikan deskripsi konten elemen dalam, satu per satu, dalam satu pengumuman. Konsolidasi elemen terkait ini membantu pengguna teknologi pendukung menemukan informasi di layar dengan lebih efisien.

Cuplikan berikut berisi bagian konten yang terkait satu sama lain, sehingga elemen penampung, instance ConstraintLayout, memiliki atribut android:screenReaderFocusable-nya yang disetel ke true dan elemen TextView dalam masing-masing memiliki atribut android:focusable yang ditetapkan ke false:

<!-- In response to a single user interaction, accessibility services announce
     both the title and the artist of the song. -->
<ConstraintLayout
    android:id="@+id/song_data_container" ...
    android:screenReaderFocusable="true">

    <TextView
        android:id="@+id/song_title" ...
        android:focusable="false"
        android:text="@string/my_song_title" />
    <TextView
        android:id="@+id/song_artist"
        android:focusable="false"
        android:text="@string/my_songwriter" />
</ConstraintLayout>

Karena layanan aksesibilitas membacakan deskripsi elemen inti dalam satu kalimat, penting untuk membuat setiap deskripsi sesingkat mungkin tetapi tetap menyampaikan maksud elemen tersebut.

Catatan:Secara umum, sebaiknya hindari membuat deskripsi konten untuk grup dengan menggabungkan teks turunannya. Tindakan ini akan membuat deskripsi grup menjadi rapuh, dan saat teks turunan berubah, deskripsi grup mungkin tidak lagi cocok dengan teks yang terlihat.

Dalam konteks daftar atau petak, pembaca layar dapat menggabungkan teks node teks turunan elemen daftar atau petak. Sebaiknya hindari memodifikasi pengumuman ini.

Grup bertingkat

Jika antarmuka aplikasi Anda menyajikan informasi multidimensi, seperti daftar acara festival harian, gunakan atribut android:screenReaderFocusable pada penampung grup dalam. Skema pelabelan ini memberikan keseimbangan yang baik antara jumlah pembacaan yang diperlukan untuk menemukan konten layar dan durasi setiap pengumuman.

Cuplikan kode berikut menunjukkan satu metode untuk memberi label pada grup di dalam grup yang lebih besar:

<!-- In response to a single user interaction, accessibility services
     announce the events for a single stage only. -->
<ConstraintLayout
    android:id="@+id/festival_event_table" ... >
    <ConstraintLayout
        android:id="@+id/stage_a_event_column"
        android:screenReaderFocusable="true">

        <!-- UI elements that describe the events on Stage A. -->

    </ConstraintLayout>
    <ConstraintLayout
        android:id="@+id/stage_b_event_column"
        android:screenReaderFocusable="true">

        <!-- UI elements that describe the events on Stage B. -->

    </ConstraintLayout>
</ConstraintLayout>

Judul dalam teks

Beberapa aplikasi menggunakan judul untuk meringkas grup teks yang muncul di layar. Jika elemen View tertentu merepresentasikan judul, Anda dapat menunjukkan tujuan judul tersebut untuk layanan aksesibilitas dengan menyetel atribut android:accessibilityHeading elemen ke true.

Pengguna layanan aksesibilitas dapat memilih untuk memilih opsi navigasi antar-judul, bukan antar-paragraf atau antar-kata. Fleksibilitas ini akan meningkatkan pengalaman navigasi teks.

Judul panel aksesibilitas

Di Android 9 (API level 28) dan yang lebih tinggi, Anda dapat memberikan judul yang mudah diakses untuk panel layar. Untuk tujuan aksesibilitas, panel adalah bagian jendela dengan tampilan visual yang mencolok, seperti konten suatu fragmen. Agar layanan aksesibilitas dapat memahami perilaku seperti jendela di panel, berikan judul deskriptif pada panel aplikasi Anda. Selanjutnya, layanan aksesibilitas dapat memberikan informasi yang lebih terperinci kepada pengguna saat tampilan atau konten panel berubah.

Untuk menentukan judul panel, gunakan atribut android:accessibilityPaneTitle, seperti ditampilkan dalam cuplikan berikut:

<!-- Accessibility services receive announcements about content changes
     that are scoped to either the "shopping cart view" section (top) or
     "browse items" section (bottom) -->
<MyShoppingCartView
     android:id="@+id/shoppingCartContainer"
     android:accessibilityPaneTitle="@string/shoppingCart" ... />

<MyShoppingBrowseView
     android:id="@+id/browseItemsContainer"
     android:accessibilityPaneTitle="@string/browseProducts" ... />

Elemen dekoratif

Jika elemen di UI Anda hanya ada untuk spacing visual atau tujuan tampilan visual, setel atribut android:importantForAccessibility ke "no".

Menambahkan tindakan aksesibilitas

Penting untuk mengizinkan pengguna layanan aksesibilitas menjalankan semua alur pengguna dalam aplikasi Anda dengan mudah. Misalnya, jika pengguna dapat menggeser item dalam daftar, tindakan ini juga dapat diekspos ke layanan aksesibilitas sehingga pengguna memiliki cara alternatif untuk menyelesaikan alur penggunaan yang sama.

Menjadikan semua tindakan mudah diakses

Pengguna TalkBack, Voice Access, atau Tombol Akses mungkin memerlukan cara alternatif untuk menyelesaikan alur penggunaan tertentu dalam aplikasi. Untuk tindakan yang terkait dengan gestur seperti tarik lalu lepas atau geser, aplikasi Anda dapat menampilkan tindakan dengan cara yang dapat diakses oleh pengguna layanan aksesibilitas.

Dengan menggunakan tindakan aksesibilitas, aplikasi dapat memberikan cara alternatif bagi pengguna untuk menyelesaikan tindakan.

Misalnya, jika aplikasi Anda memungkinkan pengguna menggeser item, Anda juga dapat menampilkan fungsi melalui tindakan aksesibilitas kustom, seperti ini:

Kotlin

ViewCompat.addAccessibilityAction(
    // View to add accessibility action
    itemView,
    // Label surfaced to user by an accessibility service
    getText(R.id.archive)
) { _, _ ->
    // Same method executed when swiping on itemView
    archiveItem()
    true
}

Java

ViewCompat.addAccessibilityAction(
    // View to add accessibility action
    itemView,
    // Label surfaced to user by an accessibility service
    getText(R.id.archive),
    (view, arguments) -> {
        // Same method executed when swiping on itemView
        archiveItem();
        return true;
    }
);

With the custom accessibility action implemented, users can access the action through the actions menu.

Make available actions understandable

When a view supports actions such as touch & hold, an accessibility service such as TalkBack announces it as "Double tap and hold to long press."

This generic announcement doesn't give the user any context about what a touch & hold action does.

To make this announcement more descriptive, you can replace the accessibility action’s announcement like so:

Kotlin

ViewCompat.replaceAccessibilityAction(
    // View that contains touch & hold action
    itemView,
    AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK,
    // Announcement read by TalkBack to surface this action
    getText(R.string.favorite),
    null
)

Java

ViewCompat.replaceAccessibilityAction(
    // View that contains touch & hold action
    itemView,
    AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_LONG_CLICK,
    // Announcement read by TalkBack to surface this action
    getText(R.string.favorite),
    null
);

This results in TalkBack announcing "Double tap and hold to favorite," helping users understand the purpose of the action.

Extend system widgets

Note: When you design your app's UI, use or extend system-provided widgets that are as far down Android's class hierarchy as possible. System-provided widgets that are far down the hierarchy already have most of the accessibility capabilities your app needs. It's easier to extend these system-provided widgets than to create your own from the more generic View, ViewCompat, Canvas, and CanvasCompat classes.

If you must extend View or Canvas directly, which might be necessary for a highly customized experience or a game level, see Make custom views more accessible.

This section uses the example of implementing a special type of Switch called TriSwitch while following best practices around extending system widgets. A TriSwitch object works similarly to a Switch object, except that each instance of TriSwitch allows the user to toggle among three possible states.

Extend from far down the class hierarchy

The Switch object inherits from several framework UI classes in its hierarchy:

View
↳ TextView
  ↳ Button
    ↳ CompoundButton
      ↳ Switch

Sebaiknya class TriSwitch yang baru diperluas secara langsung dari class Switch. Dengan cara ini, framework aksesibilitas Android menyediakan sebagian besar kemampuan aksesibilitas yang diperlukan class TriSwitch:

  • Tindakan aksesibilitas: informasi untuk sistem tentang cara layanan aksesibilitas dapat mengemulasi setiap kemungkinan input pengguna yang dilakukan pada objek TriSwitch. (Diwarisi dari View.)
  • Peristiwa aksesibilitas: informasi untuk layanan aksesibilitas tentang setiap cara agar tampilan objek TriSwitch dapat berubah saat layar dimuat ulang atau diupdate. (Diwarisi dari View.)
  • Karakteristik: detail tentang setiap objek TriSwitch, seperti konten teks yang ditampilkannya. (Diwarisi dari TextView.)
  • Informasi status: deskripsi status objek TriSwitch saat ini, seperti "dicentang" atau "tidak dicentang". (Diwarisi dari CompoundButton.)
  • Deskripsi teks tentang status: penjelasan berbasis teks tentang apa yang direpresentasikan oleh setiap status. (Diwarisi dari Switch.)

Perilaku dari Switch dan superclass-nya hampir sama dengan perilaku untuk objek TriSwitch. Oleh karena itu, implementasi Anda dapat berfokus pada perluasan jumlah kemungkinan status dari dua menjadi tiga.

Menentukan peristiwa kustom

Saat Anda memperluas widget sistem, Anda mungkin mengubah aspek tentang cara pengguna berinteraksi dengan widget tersebut. Penting untuk menentukan perubahan interaksi ini sehingga layanan aksesibilitas dapat mengupdate widget aplikasi Anda seolah-olah pengguna berinteraksi dengan widget secara langsung.

Pedoman umumnya adalah untuk setiap callback berbasis tampilan yang diganti, Anda juga perlu menentukan ulang tindakan aksesibilitas yang sesuai dengan mengganti ViewCompat.replaceAccessibilityAction(). Dalam pengujian aplikasi, Anda dapat memvalidasi perilaku tindakan yang dtentukan ulang tersebut dengan memanggil ViewCompat.performAccessibilityAction().

Cara kerja prinsip ini untuk objek TriSwitch

Tidak seperti objek Switch biasa, mengetuk siklus objek TriSwitch akan melalui tiga kemungkinan status. Oleh karena itu, tindakan aksesibilitas ACTION_CLICK yang terkait perlu diperbarui:

Kotlin

class TriSwitch(context: Context) : Switch(context) {
    // 0, 1, or 2
    var currentState: Int = 0
        private set

    init {
        updateAccessibilityActions()
    }

    private fun updateAccessibilityActions() {
        ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK,
            action-label) {
            view, args -> moveToNextState()
        })
    }

    private fun moveToNextState() {
        currentState = (currentState + 1) % 3
    }
}

Java

public class TriSwitch extends Switch {
    // 0, 1, or 2
    private int currentState;

    public int getCurrentState() {
        return currentState;
    }

    public TriSwitch() {
        updateAccessibilityActions();
    }

    private void updateAccessibilityActions() {
        ViewCompat.replaceAccessibilityAction(this, ACTION_CLICK,
            action-label, (view, args) -> moveToNextState());
    }

    private void moveToNextState() {
        currentState = (currentState + 1) % 3;
    }
}

Menggunakan petunjuk selain warna

Untuk membantu pengguna yang mengalami kekurangan daya penglihatan terhadap warna, gunakan petunjuk selain warna untuk membedakan elemen UI dalam layar aplikasi Anda. Teknik ini dapat mencakup penggunaan berbagai bentuk atau ukuran, pemberian pola teks atau visual, atau penambahan respons berbasis audio atau sentuhan (haptic) untuk menandai perbedaan elemen.

Gambar 1 menunjukkan dua versi aktivitas. Versi pertama hanya menggunakan warna untuk membedakan antara dua kemungkinan tindakan dalam alur kerja. Versi kedua menggunakan praktik terbaik yang menyertakan bentuk dan teks selain warna untuk menandai perbedaan antara kedua opsi tersebut:

Gambar 1. Contoh pembuatan elemen UI hanya menggunakan warna (kiri) dan penggunaan warna, bentuk, dan teks (kanan).

Menjadikan konten media lebih mudah diakses

Jika Anda mengembangkan aplikasi yang menyertakan konten media, seperti klip video atau rekaman audio, coba dukung pengguna dengan berbagai jenis aksesibilitas yang diperlukan untuk memahami materi ini. Secara khusus, sebaiknya Anda melakukan hal-hal berikut:

  • Menyertakan kontrol yang memungkinkan pengguna menjeda atau menghentikan media, mengubah volume, dan mengaktifkan/menonaktifkan subtitel (teks).
  • Jika video menyajikan informasi yang penting untuk menyelesaikan alur kerja, berikan konten yang sama dalam format alternatif, seperti transkrip.

Referensi lainnya

Untuk mempelajari lebih lanjut cara menjadikan aplikasi lebih mudah diakses, lihat referensi tambahan berikut:

Codelab

Postingan blog