Principi per migliorare l'accessibilità delle app

Per aiutare gli utenti con esigenze di accessibilità, il framework Android consente di creare un servizio di accessibilità in grado di presentare contenuti delle app agli utenti e utilizzano le app per loro conto.

Android offre diversi servizi di accessibilità di sistema, tra cui:

  • TalkBack: Aiuta le persone ipovedenti o non vedenti. Annuncia i contenuti tramite una voce sintetizzata ed eseguire azioni su un'app in risposta ai gesti dell'utente.
  • Switch Access: aiuta le persone con disabilità motorie. Mette in evidenza gli elementi interattivi ed esegue azioni in risposta alla pressione di un pulsante da parte dell'utente. Consente il controllo del dispositivo usando solo uno o due pulsanti.

Per aiutare le persone con esigenze di accessibilità a usare correttamente la tua app, deve seguire le best practice descritte in questa pagina, che si basano le linee guida descritte in Creare più app accessibili.

Ognuna di queste best practice, descritta nelle sezioni che seguono, può migliorare ulteriormente l'accessibilità della tua app:

Etichetta gli elementi
Gli utenti devono essere in grado di comprendere i contenuti e lo scopo di ogni sessione e significativo elemento UI all'interno della tua app.
Aggiungere azioni di accessibilità
L'aggiunta di azioni di accessibilità consente agli utenti di usufruire per completare i flussi di utenti critici all'interno della tua app.
Estendi i widget di sistema
Punta sugli elementi view che include il framework, anziché creando le tue viste personalizzate. La vista del framework e le classi widget sono già che offrono la maggior parte delle funzionalità di accessibilità necessarie alla tua app.
Utilizzare segnali diversi dal colore
Gli utenti devono essere in grado di distinguere chiaramente tra le categorie di elementi in una UI. Per farlo, usa pattern e posizione, insieme al colore, per esprimere questi e le differenze.
Rendere più accessibili i contenuti multimediali
Aggiungi descrizioni ai contenuti video o audio della tua app in modo che gli utenti che fruiscono di questi contenuti non devono affidarsi a segnali interamente visivi o sonori.

Elementi dell'etichetta

È importante fornire agli utenti etichette utili e descrittive per ogni un elemento UI interattivo nella tua app. Ogni etichetta deve spiegare il significato e lo scopo di un particolare elemento. Gli screen reader come TalkBack possono annunciare queste etichette agli utenti.

Nella maggior parte dei casi, specifichi la descrizione di un elemento UI nel layout contenente l'elemento. In genere, si aggiungono etichette utilizzando L'attributo contentDescription, come spiegato nella guida alla creazione di app più accessibili. Là ci sono diverse altre tecniche di etichettatura descritte nelle sezioni seguenti.

Elementi modificabili

Quando si etichettano elementi modificabili, ad esempio: EditText oggetti, è utile mostrare testo che fornisce un esempio di input valido nell'elemento stesso, oltre a rendendo questo testo di esempio disponibile agli screen reader. In queste situazioni, puoi usare l'attributo android:hint, come mostrato nello snippet seguente:

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

In questo caso, l'oggetto View deve avere il suo attributo android:labelFor impostato con l'ID dell'elemento EditText. Per ulteriori dettagli, consulta le seguenti risorse: .

Coppie di elementi in cui uno descrive l'altro

È comune che un elemento EditText abbia un View che descrive cosa gli utenti devono inserisci nell'elemento EditText. Puoi indicare questa relazione impostando attributo android:labelFor dell'oggetto View.

Un esempio di etichettatura di queste coppie di elementi è riportato nel seguente snippet:

<!-- 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" ... />

Elementi in una raccolta

Quando aggiungi etichette agli elementi di una collezione, ogni etichetta deve essere univoca. In questo modo, i servizi di accessibilità del sistema possono fare riferimento a un solo elemento visualizzato sullo schermo quando viene annunciata un'etichetta. Questa corrispondenza consente agli utenti di sapere possono scorrere l'interfaccia utente o spostare lo stato attivo su un elemento che che hanno già scoperto.

In particolare, includi testo aggiuntivo o informazioni contestuali nella di elementi all'interno di layout riutilizzati, ad esempio RecyclerView in modo che ogni elemento secondario venga identificato in modo univoco.

Per farlo, imposta la descrizione dei contenuti come parte dell'implementazione dell'adattatore, come mostrato nel seguente snippet di codice:

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")
    }
}

Gruppi di contenuti correlati

Se la tua app visualizza diversi elementi UI che formano un gruppo naturale, ad esempio i dettagli di una canzone o gli attributi di un messaggio, disponi questi elementi all'interno di un container, che di solito è una sottoclasse ViewGroup. Imposta il contenitore dell'oggetto android:screenReaderFocusable a true e l'attributo di ogni oggetto interno android:focusable a false. In questo modo, i servizi di accessibilità possono presentare elementi descrizioni dei contenuti, una dopo l'altra, in un unico annuncio. Questo consolidamento degli elementi correlati aiuta gli utenti delle tecnologie per la disabilità a scoprire le informazioni sullo schermo in modo più efficiente.

Il seguente snippet include contenuti correlati a uno di questi un'altra istanza, quindi l'elemento container, un'istanza di ConstraintLayout, ha la sua Attributo android:screenReaderFocusable impostato su true e interno L'attributo android:focusable di ogni elemento TextView è impostato su 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>

Poiché i servizi di accessibilità annunciano gli elementi interni, in un singola frase, è importante che ogni descrizione sia il più breve possibile comunicando comunque il significato dell'elemento.

Nota: in generale, dovresti evitare di creare una descrizione dei contenuti per un gruppo aggregando il testo dei relativi bambini. In questo modo la descrizione del gruppo è debole e quando il testo modifiche secondarie, la descrizione del gruppo potrebbe non corrispondere più al testo visibile.

In un elenco o in un contesto di griglia, uno screen reader può consolidare il testo di un elenco. nodi di testo secondari degli elementi della griglia. È meglio evitare di modificarlo annuncio.

Gruppi nidificati

Se l'interfaccia della tua app presenta informazioni multidimensionali, ad esempio una elenco giornaliero degli eventi del festival, utilizza l'android:screenReaderFocusable sui container interni del gruppo. Questo schema di etichettatura offre una buona tra il numero di annunci necessari per scoprire le contenuti e la durata di ciascun annuncio.

Il seguente snippet di codice mostra un metodo per etichettare i gruppi all'interno di Gruppi più grandi:

<!-- 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>

Intestazioni all'interno del testo

Alcune app utilizzano le intestazioni per riassumere gruppi di testo che appaiono sullo schermo. Se un particolare elemento View rappresenta un'intestazione, puoi indicarne lo scopo per i servizi di accessibilità impostando l'elemento Attributo android:accessibilityHeading a true.

Gli utenti dei servizi di accessibilità possono scegliere di spostarsi tra le intestazioni invece che tra i paragrafi o tra le parole. Questa flessibilità migliora esperienza di navigazione testuale.

Titoli del riquadro Accessibilità

In Android 9 (livello API 28) e versioni successive, puoi fornire titoli ottimizzati per l'accessibilità per i riquadri di uno schermo. Per l'accessibilità scopi, un riquadro è una parte visivamente distinta di una finestra, come contenuti di un frammento. Affinché i servizi di accessibilità possano comprendere comportamento di tipo finestra, assegna titoli descrittivi al comportamento riquadri. I servizi di accessibilità possono quindi fornire informazioni più granulari agli utenti quando l'aspetto o i contenuti di un riquadro cambiano.

Per specificare il titolo di un riquadro, utilizza il metodo android:accessibilityPaneTitle come mostrato nello snippet seguente:

<!-- 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" ... />

Elementi decorativi

Se un elemento nell'interfaccia utente esiste solo per la spaziatura o l'aspetto visivo scopi, impostane android:importantForAccessibility a "no".

Aggiungi azioni di accessibilità

È importante consentire agli utenti dei servizi di accessibilità di eseguire facilmente i flussi di utenti all'interno dell'app. Ad esempio, se un utente può scorrere su un elemento in una elenco, questa azione può essere esposta anche ai servizi di accessibilità in modo che gli utenti un modo alternativo per completare la stessa procedura.

Rendi accessibili tutte le azioni

Un utente di TalkBack, Voice Access o Switch Access potrebbero aver bisogno di metodi alternativi per completare alcune procedure l'app. Per le azioni associate ai gesti, ad esempio trascinamento e scorrimento, la tua app può esporre le azioni in un modo accessibile agli utenti di di accessibilità di Google.

Utilizzando le azioni di accessibilità, l'app può fornire agli utenti modi alternativi per completare un'azione.

Ad esempio, se l'app consente agli utenti di scorrere su un elemento, puoi anche esponi la funzionalità tramite un'azione di accessibilità personalizzata, come questa:

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

È preferibile che la nuova classe TriSwitch si espanda direttamente dal Switch . In questo modo, l'accessibilità Android . fornisce la maggior parte delle funzionalità di accessibilità della classe TriSwitch esigenze:

  • Azioni di accessibilità: informazioni per il sistema su come l'accessibilità servizi possono emulare ogni possibile input utente eseguito su un TriSwitch . (Ereditata da View).
  • Eventi di accessibilità: informazioni per i servizi di accessibilità relativi a ogni è possibile che l'aspetto di un oggetto TriSwitch possa cambiare quando lo schermo o gli aggiornamenti. (Ereditata da View).
  • Caratteristiche: dettagli di ogni oggetto TriSwitch, ad esempio i contenuti del testo visualizzato. (Ereditata da TextView).
  • Informazioni sullo stato: descrizione dello stato attuale di un oggetto TriSwitch, ad esempio "selezionata" o "deselezionata". (Ereditata da CompoundButton).
  • Descrizione testuale dello stato: spiegazione testuale di ogni stato che rappresenta. (Ereditata da Switch).

Questo comportamento di Switch e delle sue superclassi è quasi lo stesso comportamento per TriSwitch oggetti. Di conseguenza, la tua implementazione può sull'espansione del numero di stati possibili da due a tre.

Definisci eventi personalizzati

Quando estendi un widget di sistema, probabilmente cambi un aspetto del modo in cui gli utenti a interagire con il widget. È importante definire queste modifiche all'interazione in modo che i servizi di accessibilità possano aggiornare il widget dell'app come se l'utente interagisce direttamente con il widget.

Come regola generale, per ogni callback basato sulle visualizzazioni che esegui l'override, Occorre anche ridefinire l'azione di accessibilità corrispondente eseguendo l'override ViewCompat.replaceAccessibilityAction() Nei test della tua app, puoi convalidare il comportamento di queste azioni ridefinite chiamata ViewCompat.performAccessibilityAction()

Come funziona questo principio per gli oggetti TriSwitch

A differenza di un normale oggetto Switch, se tocchi un oggetto TriSwitch si passa attraverso tre stati possibili. Di conseguenza, l'accessibilità di ACTION_CLICK azione deve essere aggiornata:

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;
    }
}

Usa segnali diversi dal colore

Per assistere gli utenti con carenze di visione dei colori, usa segnali diversi dal colore per distinguere gli elementi UI nelle schermate dell'app. Queste tecniche possono ad esempio l'utilizzo di forme o dimensioni diverse, l'aggiunta di testo o motivi visivi o aggiungendo un feedback audio o basato sul tocco (aptico) per contrassegnare gli elementi. le differenze.

La figura 1 mostra due versioni di un'attività. Una versione utilizza solo il colore per distinguere tra due possibili azioni in un flusso di lavoro. L'altra versione utilizza la best practice di includere forme e testo oltre al colore per per evidenziare le differenze tra le due opzioni:

. Figura 1. Esempi di creazione di elementi UI usando solo il colore (a sinistra) e utilizzando colori, forme e testo (a destra).

Rendere i contenuti multimediali più accessibili

Se stai sviluppando un'app che include contenuti multimediali, ad esempio un video clip o una registrazione audio, prova a sostenere gli utenti con diversi tipi di le esigenze di accessibilità per comprendere questo materiale. In particolare, ti invitiamo a procedere nel seguente modo:

  • Includi controlli che consentono agli utenti di mettere in pausa o interrompere i contenuti multimediali, modifica il volume e attiva/disattiva i sottotitoli.
  • Se un video presenta informazioni fondamentali per il completamento di un flusso di lavoro, Fornire gli stessi contenuti in un formato alternativo, ad esempio una trascrizione.

Risorse aggiuntive

Per scoprire di più su come rendere la tua app più accessibile, consulta le seguenti risorse risorse aggiuntive:

Codelab

Blog post