Prinsip-prinsip untuk meningkatkan aksesibilitas aplikasi

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

Android menyediakan beberapa layanan aksesibilitas sistem, termasuk:

  • TalkBack: membantu orang yang memiliki gangguan penglihatan atau tunanetra. Fitur ini mengumumkan konten melalui menyintesis suara dan melakukan tindakan pada aplikasi sebagai respons terhadap {i>gestures <i}pengguna.
  • Tombol Akses: membantu orang-orang yang memiliki disabilitas motorik. Ini menyoroti elemen-elemen interaktif dan melakukan tindakan sebagai respons ketika pengguna menekan tombol. Hal ini memungkinkan mengontrol perangkat dengan hanya menggunakan satu atau dua tombol.

Untuk membantu orang dengan kebutuhan aksesibilitas berhasil menggunakan aplikasi Anda, aplikasi harus mengikuti praktik terbaik yang dijelaskan di halaman ini, yang didasarkan pedoman yang dijelaskan dalam Membuat aplikasi dapat diakses.

Setiap praktik terbaik ini, yang diuraikan di bagian berikut, dapat lebih meningkatkan aksesibilitas aplikasi Anda:

Elemen label
Pengguna harus dapat memahami konten dan tujuan setiap interaktif yang bermakna dalam aplikasi Anda.
Menambahkan tindakan aksesibilitas
Dengan menambahkan tindakan aksesibilitas, Anda dapat memungkinkan pengguna aksesibilitas untuk menyelesaikan alur penggunaan yang 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 dengan jelas kategori elemen dalam UI. Untuk melakukannya, gunakan pola dan posisi serta warna untuk menunjukkan perbedaannya.
Menjadikan konten media lebih mudah diakses
Tambahkan deskripsi ke konten video atau audio aplikasi Anda agar pengguna yang menikmati konten ini tidak perlu bergantung pada petunjuk visual atau aural sepenuhnya.

Elemen label

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

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

Elemen yang dapat diedit

Saat melabeli elemen yang dapat diedit, seperti EditText, sebaiknya tampilkan teks yang memberikan contoh input yang valid dalam elemen itu sendiri, selain membuat contoh teks ini tersedia untuk 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 disetel ke ID elemen EditText. Untuk detail selengkapnya, lihat referensi berikut bagian.

Menyambungkan elemen yang salah satunya mendeskripsikan elemen lainnya

Biasanya elemen EditText memiliki elemen Objek View yang menjelaskan hal yang harus dilakukan pengguna masukkan dalam elemen EditText. Anda bisa menunjukkan hubungan ini dengan mengatur 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 ke satu sama lain saat mengumumkan label. Korespondensi ini memungkinkan pengguna mengetahui kapan mereka menelusuri UI atau saat mereka memindahkan fokus ke elemen yang yang telah mereka temukan.

Secara khusus, sertakan teks tambahan atau informasi kontekstual dalam elemen dalam tata letak yang digunakan kembali—seperti RecyclerView objek—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 bagian dalam elemen deskripsi konten, satu per satu, dalam satu pengumuman. Konsolidasi elemen terkait ini membantu pengguna teknologi alat bantu/assistive technology menemukan informasi di layar dengan lebih efisien.

Cuplikan berikut berisi konten yang terkait dengan satu satu lagi, jadi elemen container, yakni instance ConstraintLayout, memiliki Atribut android:screenReaderFocusable disetel ke true dan bagian dalam Setiap elemen TextView memiliki atribut android:focusable yang disetel 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, Anda harus menghindari pembuatan deskripsi konten untuk grup dengan menggabungkan teks anak-anak. Hal tersebut akan membuat deskripsi grup menjadi rapuh, dan jika teks turunan, deskripsi grup mungkin tidak lagi sesuai dengan teks yang terlihat.

Dalam daftar atau konteks {i>grid<i}, {i>screen reader<i} dapat menggabungkan teks dari daftar atau node teks turunan elemen grid. Sebaiknya hindari memodifikasi pengumuman.

Grup bertingkat

Jika antarmuka aplikasi Anda menyajikan informasi multidimensi, seperti daftar acara festival harian, gunakan android:screenReaderFocusable pada container grup bagian dalam. Skema pelabelan ini memberikan gambaran keseimbangan antara jumlah pengumuman yang diperlukan untuk menemukan 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 panel, berikan judul deskriptif pada Google Analytics. 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 memungkinkan pengguna layanan aksesibilitas untuk melakukan semua alur pengguna dalam aplikasi Anda. Misalnya, jika pengguna bisa menggeser item di daftar, tindakan ini juga dapat diekspos ke layanan aksesibilitas sehingga pengguna memiliki cara alternatif untuk menyelesaikan alur pengguna yang sama.

Membuat semua tindakan dapat diakses

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

Menggunakan tindakan aksesibilitas, aplikasi dapat menyediakan cara alternatif bagi pengguna untuk menyelesaikan suatu tindakan.

Misalnya, jika aplikasi Anda memungkinkan pengguna untuk menggeser item, Anda juga bisa mengekspos fungsionalitas 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 actions 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, aksesibilitas Android kerangka kerja menyediakan sebagian besar kemampuan aksesibilitas class TriSwitch kebutuhan:

  • Tindakan aksesibilitas: informasi untuk sistem tentang cara aksesibilitas layanan dapat mengemulasi setiap kemungkinan input pengguna yang dilakukan pada TriSwitch . (Diwarisi dari View.)
  • Peristiwa aksesibilitas: informasi untuk layanan aksesibilitas tentang setiap cara yang mungkin agar tampilan objek TriSwitch dapat berubah saat layar pembaruan atau pembaruan. (Diwarisi dari View.)
  • Karakteristik: detail tentang setiap objek TriSwitch, seperti dari teks apa pun 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 saja setiap status diwakili oleh variabel tersebut. (Diwarisi dari Switch.)

Perilaku dari Switch dan superclass-nya hampir perilaku yang sama untuk objek TriSwitch. Oleh karena itu, penerapan Anda dapat fokus pada memperluas jumlah kemungkinan keadaan 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 mendefinisikan perubahan interaksi ini sehingga layanan aksesibilitas bisa memperbarui widget aplikasi Anda seolah-olah pengguna berinteraksi dengan widget secara langsung.

Panduan umumnya adalah untuk setiap callback berbasis tampilan yang Anda ganti, 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 melalui siklus 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-teknik ini bisa termasuk menggunakan berbagai bentuk atau ukuran, menyediakan teks atau pola visual, atau menambahkan respons berbasis audio atau sentuhan (haptic) untuk menandai elemen perbedaan tersebut.

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 menggunakan warna saja (kiri) dan menggunakan 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:

  • Sertakan kontrol yang memungkinkan pengguna menjeda atau menghentikan media, mengubah volume, dan mengaktifkan atau menonaktifkan subtitel (teks).
  • Jika video menyajikan informasi penting untuk menyelesaikan alur kerja, menyediakan 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