Prinzipien zur Verbesserung der Barrierefreiheit von Apps

Mit dem Android-Framework können Sie eine Bedienungshilfe erstellen, die Nutzern Inhalte aus Apps präsentieren und auch Apps in ihrem Namen betreiben kann, um Nutzer bei den Anforderungen an die Barrierefreiheit zu unterstützen.

Android bietet verschiedene Bedienungshilfen, darunter:

  • TalkBack: Hilft Menschen mit eingeschränktem Sehvermögen oder Blindheit. Sie meldet Inhalte über eine synthetisierte Stimme und führt als Reaktion auf Nutzergesten Aktionen in einer App aus.
  • Schalterzugriff: Unterstützt Personen mit motorischen Beeinträchtigungen. Sie hebt interaktive Elemente hervor und führt Aktionen aus, wenn der Nutzer auf eine Schaltfläche drückt. Sie können das Gerät mit nur einer oder zwei Tasten steuern.

Damit Nutzer mit Anforderungen an Barrierefreiheit Ihre App erfolgreich verwenden können, muss Ihre App den auf dieser Seite beschriebenen Best Practices entsprechen, die auf den Richtlinien unter Barrierefreiheit von Apps verbessern aufbauen.

Mit den folgenden Best Practices, die in den folgenden Abschnitten beschrieben werden, können Sie die Barrierefreiheit Ihrer App weiter verbessern:

Label-Elemente
Nutzer müssen den Inhalt und Zweck jedes interaktiven und aussagekräftigen UI-Elements in Ihrer App verstehen können.
Aktionen für Bedienungshilfen hinzufügen
Durch das Hinzufügen von Aktionen für Bedienungshilfen können Sie es Nutzern von Bedienungshilfen ermöglichen, wichtige Nutzerflüsse innerhalb Ihrer App auszuführen.
System-Widgets erweitern
Bauen Sie auf den Ansichtselementen des Frameworks auf, anstatt eigene benutzerdefinierte Ansichten zu erstellen. Die Ansichts- und Widget-Klassen des Frameworks bieten bereits die meisten der Bedienungshilfen, die Ihre App benötigt.
Andere Hinweise als Farbe verwenden
Nutzer müssen in einer UI klar zwischen Elementkategorien unterscheiden können. Verwenden Sie dazu Muster, Position und Farbe, um diese Unterschiede auszudrücken.
Medieninhalte barrierefreier gestalten
Füge den Video- oder Audioinhalten deiner App Beschreibungen hinzu, damit Nutzer, die diese Inhalte ansehen, sich nicht auf vollständig visuelle oder akustische Signale verlassen müssen.

Labelelemente

Es ist wichtig, den Nutzern nützliche und beschreibende Labels für jedes interaktive UI-Element in Ihrer App zur Verfügung zu stellen. Mit jedem Label müssen die Bedeutung und der Zweck eines bestimmten Elements erläutert werden. Screenreader wie TalkBack können Nutzern diese Labels vorlesen.

In den meisten Fällen geben Sie die Beschreibung eines UI-Elements in der Layout-Ressourcendatei an, die das Element enthält. Normalerweise fügen Sie Labels mit dem Attribut contentDescription hinzu. Eine Erläuterung dazu finden Sie im Leitfaden Barrierefreiheit von Apps verbessern. In den folgenden Abschnitten werden weitere Labeltechniken beschrieben.

Bearbeitbare Elemente

Wenn Sie bearbeitbare Elemente wie EditText-Objekte mit Labels versehen, ist es hilfreich, Text einzufügen, der ein Beispiel für eine gültige Eingabe im Element selbst liefert. Außerdem wird dieser Beispieltext für Screenreader verfügbar gemacht. In diesen Fällen können Sie das Attribut android:hint verwenden, wie im folgenden Snippet gezeigt:

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

In diesem Fall muss das android:labelFor-Attribut des View-Objekts auf die ID des EditText-Elements festgelegt sein. Weitere Informationen finden Sie im folgenden Abschnitt.

Elementpaare, bei denen das eine das andere beschreibt

Im Allgemeinen hat ein EditText-Element ein entsprechendes View-Objekt, das beschreibt, was Nutzer in das EditText-Element eingeben müssen. Sie können diese Beziehung angeben, indem Sie das Attribut android:labelFor des View-Objekts festlegen.

Im folgenden Snippet sehen Sie ein Beispiel für die Kennzeichnung solcher Elementpaare:


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

Elemente in einer Sammlung

Wenn Sie den Elementen einer Sammlung Beschriftungen hinzufügen, müssen diese eindeutig sein. Auf diese Weise können sich die Bedienungshilfen des Systems bei der Ankündigung eines Labels auf genau ein Bildschirmelement beziehen. So wissen Nutzer, wann sie die Benutzeroberfläche durchlaufen oder den Fokus auf ein bereits gefundenes Element verschieben.

Fügen Sie insbesondere zusätzliche Text- oder Kontextinformationen in Elemente von wiederverwendeten Layouts wie RecyclerView-Objekten ein, sodass jedes untergeordnete Element eindeutig identifiziert wird.

Dazu legen Sie die Inhaltsbeschreibung als Teil der Adapterimplementierung fest, wie im folgenden Code-Snippet gezeigt:

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

Gruppen ähnlicher Inhalte

Wenn in Ihrer App mehrere UI-Elemente angezeigt werden, die eine natürliche Gruppe bilden, z. B. Details zu einem Song oder Attribute einer Nachricht, ordnen Sie diese Elemente in einem Container an. Dieser ist normalerweise eine abgeleitete Klasse von ViewGroup. Setzen Sie das Attribut android:screenReaderFocusable des Containerobjekts auf true und das Attribut android:focusable jedes inneren Objekts auf false. Auf diese Weise können Bedienungshilfen die Inhaltsbeschreibungen der inneren Elemente nacheinander in einer einzigen Ankündigung präsentieren. Diese Konsolidierung zusammengehöriger Elemente hilft Nutzenden von Hilfstechnologien, die Informationen auf dem Bildschirm effizienter zu finden.

Das folgende Snippet enthält Inhalte, die zueinander in Beziehung stehen. Daher wird für das Containerelement, eine Instanz von ConstraintLayout, das Attribut android:screenReaderFocusable auf true und für das innere TextView-Element das Attribut android:focusable auf false festgelegt:

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

Da Bedienungshilfen die Beschreibungen der inneren Elemente in einer einzigen Äußerung aussprechen, ist es wichtig, jede Beschreibung so kurz wie möglich zu halten und gleichzeitig die Bedeutung des Elements zu vermitteln.

Hinweis:Im Allgemeinen sollten Sie keine Inhaltsbeschreibung für eine Gruppe erstellen, indem Sie den Text ihrer untergeordneten Elemente aggregieren. Dadurch wird die Beschreibung der Gruppe fehlerhaft und wenn sich der Text eines untergeordneten Elements ändert, stimmt die Beschreibung der Gruppe möglicherweise nicht mehr mit dem sichtbaren Text überein.

In einem Listen- oder Rasterkontext kann ein Screenreader den Text einer Liste oder der untergeordneten Textknoten eines Rasterelements zusammenfassen. Sie sollten diese Mitteilung möglichst nicht ändern.

Verschachtelte Gruppen

Wenn die Schnittstelle Ihrer App mehrdimensionale Informationen liefert, z. B. eine tägliche Liste von Festivalveranstaltungen, verwenden Sie das Attribut android:screenReaderFocusable für die inneren Gruppencontainer. Dieses Labeling-Schema bietet ein gutes Gleichgewicht zwischen der Anzahl der Ankündigungen, die zum Erkennen des Bildschirminhalts erforderlich sind, und der Länge der jeweiligen Ankündigungen.

Das folgende Code-Snippet zeigt eine Methode, um Gruppen innerhalb größerer Gruppen mit Labels zu versehen:

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

Überschriften im Text

Einige Apps verwenden Überschriften, um Textgruppen zusammenzufassen, die auf dem Bildschirm angezeigt werden. Wenn ein bestimmtes View-Element eine Überschrift darstellt, können Sie seinen Zweck für Bedienungshilfen angeben. Dazu setzen Sie das Attribut android:accessibilityHeading des Elements auf true.

Nutzer von Bedienungshilfen können zwischen Überschriften statt zwischen Absätzen oder zwischen Wörtern wechseln. Diese Flexibilität verbessert die Textnavigation.

Titel des Bereichs „Bedienungshilfen“

Unter Android 9 (API-Level 28) und höher können Sie für die Bildschirmbereiche barrierefreie Titel angeben. Aus Gründen der Zugänglichkeit ist ein Bereich ein visuell deutlicher Teil eines Fensters, z. B. der Inhalt eines Fragments. Damit Bedienungshilfen das fensterähnliche Verhalten eines Bereichs verstehen, geben Sie den Bereichen Ihrer App aussagekräftige Titel. Bedienungshilfen können Nutzern dann detailliertere Informationen liefern, wenn sich das Aussehen oder der Inhalt eines Bereichs ändert.

Um den Titel eines Bereichs anzugeben, verwenden Sie das Attribut android:accessibilityPaneTitle, wie im folgenden Snippet gezeigt:

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

Dekorative Elemente

Wenn ein Element in Ihrer UI nur für visuelle Abstände oder die visuelle Darstellung vorhanden ist, setzen Sie das Attribut android:importantForAccessibility auf "no".

Aktionen für Bedienungshilfen hinzufügen

Es ist wichtig, Nutzern von Bedienungshilfen die Möglichkeit zu geben, alle Nutzerflüsse innerhalb Ihrer App einfach auszuführen. Wenn ein Nutzer beispielsweise über ein Element in einer Liste wischen kann, kann diese Aktion auch über Bedienungshilfen verfügbar sein, sodass Nutzer eine alternative Möglichkeit haben, denselben Nutzerfluss auszuführen.

Alle Aktionen barrierefrei machen

Nutzer von TalkBack, Voice Access oder Schalterzugriff benötigen möglicherweise alternative Möglichkeiten, um bestimmte Abläufe in der App auszuführen. Bei Aktionen in Verbindung mit Touch-Gesten wie Drag-and-drop oder Wischen kann Ihre App die Aktionen auf eine Weise darstellen, die für Nutzer von Bedienungshilfen zugänglich ist.

Mithilfe von Aktionen für Bedienungshilfen kann die App Nutzern alternative Möglichkeiten bieten, eine Aktion auszuführen.

Wenn Nutzer in Ihrer App beispielsweise über ein Element wischen können, können Sie die Funktionalität auch über eine benutzerdefinierte Bedienungshilfenaktion wie die folgende darstellen:

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

Es empfiehlt sich, die neue TriSwitch-Klasse direkt aus der Switch-Klasse zu erweitern. Auf diese Weise bietet das Android-Framework für Barrierefreiheit die meisten der Bedienungshilfen, die die Klasse TriSwitch benötigt:

  • Bedienungshilfen:Informationen für das System, wie Bedienungshilfen jede mögliche Nutzereingabe emulieren können, die für ein TriSwitch-Objekt ausgeführt wird. (Von View übernommen.)
  • Ereignisse für Bedienungshilfen:Informationen für Bedienungshilfen zu allen möglichen Arten, wie sich die Darstellung eines TriSwitch-Objekts ändern kann, wenn der Bildschirm aktualisiert oder aktualisiert wird. (Von View übernommen.)
  • Merkmale:Details zu jedem TriSwitch-Objekt, z. B. der Inhalt des angezeigten Textes. (Von TextView übernommen.)
  • Statusinformationen: Beschreibung des aktuellen Status eines TriSwitch-Objekts, z. B. „aktiviert“ oder „nicht aktiviert“. (Von CompoundButton übernommen.)
  • Textbeschreibung des Bundesstaats:Textbasierte Erläuterung der einzelnen Bundesstaaten. (Von Switch übernommen.)

Das Verhalten von Switch und den zugehörigen Oberklassen ist fast das gleiche für TriSwitch-Objekte. Daher kann sich Ihre Implementierung darauf konzentrieren, die Anzahl der möglichen Status von zwei auf drei zu erhöhen.

Benutzerdefinierte Ereignisse definieren

Wenn Sie ein System-Widget erweitern, ändern Sie wahrscheinlich einen Aspekt der Interaktion der Nutzer mit diesem Widget. Diese Interaktionsänderungen müssen so definiert werden, dass Bedienungshilfen das Widget Ihrer App so aktualisieren können, als würde der Nutzer direkt mit dem Widget interagieren.

Als allgemeine Richtlinie gilt, dass du für jeden aufrufbasierten Callback, den du überschreiben möchtest, auch die entsprechende Bedienungshilfenaktion neu definieren musst. Überschreiben Sie dazu ViewCompat.replaceAccessibilityAction(). In den Tests Ihrer App können Sie das Verhalten dieser neu definierten Aktionen validieren, indem Sie ViewCompat.performAccessibilityAction() aufrufen.

Funktionsweise dieses Prinzips für TriSwitch-Objekte

Im Gegensatz zu einem gewöhnlichen Switch-Objekt werden beim Tippen auf ein TriSwitch-Objekt drei mögliche Zustände angezeigt. Daher muss die entsprechende Bedienungshilfen-Aktion ACTION_CLICK aktualisiert werden:

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

Andere Hinweise als Farbe verwenden

Um Nutzer bei Farbsinnstörungen zu unterstützen, solltest du andere Hinweise als Farben verwenden, um UI-Elemente auf den Bildschirmen deiner App voneinander abzugrenzen. Zu diesen Techniken gehören die Verwendung verschiedener Formen oder Größen, das Bereitstellen von Text- oder visuellen Mustern oder das Hinzufügen von audio- oder berührungsbasiertem (haptischem) Feedback, um die Unterschiede der Elemente zu kennzeichnen.

Abbildung 1 zeigt zwei Versionen einer Aktivität. Bei einer Version wird nur die Farbe verwendet, um zwischen zwei möglichen Aktionen in einem Workflow zu unterscheiden. In der anderen Version wird die Best Practice angewendet, zusätzlich zu Farben Formen und Text anzugeben, um die Unterschiede zwischen den beiden Optionen hervorzuheben:

Abbildung 1: Beispiele für das Erstellen von UI-Elementen mit Farbe (links) und mit Farbe, Formen und Text (rechts)

Medieninhalte barrierefreier gestalten

Wenn du eine App entwickelst, die Medieninhalte wie Videoclips oder Audioaufnahmen enthält, solltest du Nutzer mit unterschiedlichen Anforderungen an die Barrierefreiheit dabei unterstützen, diese Inhalte zu verstehen. Insbesondere empfehlen wir Folgendes:

  • Steuerelemente enthalten, mit denen Nutzer die Medienwiedergabe pausieren oder stoppen, die Lautstärke ändern und Untertitel aktivieren bzw. deaktivieren können.
  • Wenn ein Video Informationen präsentiert, die für den Abschluss eines Workflows wichtig sind, stellen Sie dieselben Inhalte in einem alternativen Format bereit, z. B. in einem Transkript.

Weitere Informationen

Weitere Informationen dazu, wie Sie die Barrierefreiheit Ihrer Anwendung verbessern können, finden Sie in den folgenden zusätzlichen Ressourcen:

Codelabs

Blogposts