Um Nutzer mit besonderen Anforderungen an die Barrierefreiheit im Internet zu unterstützen, kannst du mit dem Android-Framework einen Bedienungshilfendienst erstellen, der Nutzern Inhalte aus Apps präsentieren und Apps in ihrem Namen bedienen kann.
Android bietet mehrere Bedienungshilfen für das System, darunter:
- TalkBack: Hilft Menschen mit eingeschränktem Sehvermögen oder Sehbehinderung. Inhalte werden mit einer synthetischen Stimme angesagt und Aktionen in einer App werden als Reaktion auf Nutzergesten ausgeführt.
- Schalterzugriff: Hilft Menschen mit motorischen Beeinträchtigungen. Sie hebt interaktive Elemente hervor und führt Aktionen aus, wenn der Nutzer eine Taste drückt. Das Gerät kann mit nur einer oder zwei Tasten gesteuert werden.
Damit Nutzer mit besonderen Anforderungen an die Barrierefreiheit deine App erfolgreich verwenden können, muss sie den Best Practices auf dieser Seite entsprechen. Diese basieren auf den Richtlinien unter Apps barrierefreier gestalten.
Die folgenden Best Practices können die Bedienungshilfen Ihrer App weiter verbessern:
- Elemente mit Labels versehen
- Nutzer müssen den Inhalt und Zweck jedes interaktiven und aussagekräftigen UI-Elements in deiner App verstehen können.
- Aktionen für Bedienungshilfen hinzufügen
- Wenn Sie Aktionen für Bedienungshilfen hinzufügen, können Nutzer von Bedienungshilfen wichtige Nutzerflüsse in Ihrer App ausführen.
- Integrierte Bedienungshilfen verwenden
- Compose bietet standardmäßig viele Bedienungshilfen. Nutzen Sie vordefinierte Verhaltensweisen für die Barrierefreiheit, um Ihre Komponenten mit wenig oder gar keinem zusätzlichen Aufwand barrierefrei zu machen. Compose bietet auch Möglichkeiten, spezifischere Anforderungen an die Barrierefreiheit im Internet zu unterstützen, die nicht von den Standardfunktionen abgedeckt werden.
- Andere Hinweise als Farben verwenden
- Nutzer müssen in der Lage sein, klar zwischen den Kategorien von Elementen in einer Benutzeroberfläche zu unterscheiden. Verwenden Sie dazu Muster und Positionen sowie Farben, um diese Unterschiede auszudrücken.
- Medieninhalte barrierefreier gestalten
- Fügen Sie den Video- oder Audioinhalten Ihrer App Beschreibungen hinzu, damit Nutzer, die diese Inhalte konsumieren, nicht ausschließlich auf visuelle oder akustische Hinweise angewiesen sind.
Labelelemente
Es ist wichtig, Nutzern für jedes interaktive UI-Element in Ihrer App nützliche und beschreibende Labels zur Verfügung zu stellen. Jedes Label muss die Semantik eines bestimmten Elements erklären, d. h. die Bedeutung und den Zweck des Elements. Screenreader wie TalkBack können diese Labels für Nutzer ansagen.
In den meisten Fällen bieten Compose APIs und Material standardmäßige Unterstützung für Bedienungshilfen. Wenn Sie die semantischen Eigenschaften eines UI-Elements jedoch manuell angeben müssen, verwenden Sie den Modifikator semantics und die Property contentDescription. Weitere Informationen zur Semantik finden Sie unter Semantik.
In den folgenden Abschnitten werden mehrere andere Labeling-Techniken beschrieben.
Bearbeitbare Elemente
Wenn Sie bearbeitbare Elemente wie Textfelder mit Labels versehen, ist es hilfreich, Text anzuzeigen, der ein Beispiel für eine gültige Eingabe im Element selbst enthält. Außerdem sollte dieser Beispieltext für Screenreader verfügbar sein. In diesen Fällen können Sie Platzhaltertext verwenden, der auch als Hinweistext bezeichnet wird.
Im folgenden Beispiel hat TextField den Parameter placeholder, der Hinweistext enthält.
val usernameState = rememberTextFieldState() TextField( state = usernameState, lineLimits = TextFieldLineLimits.SingleLine, placeholder = { Text("Enter Username") } )
Es ist auch üblich, dass ein Textfeld ein entsprechendes beschreibendes Label hat, das beschreibt, was Nutzer eingeben müssen.
Im folgenden Beispiel hat das TextField einen label-Parameter, der eine Beschreibung der Barrierefreiheit im Internet enthält.
TextField( state = rememberTextFieldState(initialText = "Hello"), label = { Text("Label") } )
Weitere Informationen zu Text und Nutzereingaben finden Sie unter Textfelder konfigurieren.
Elemente in einer Sammlung
Wenn Sie den Elementen einer Sammlung Labels hinzufügen, muss jedes Label eindeutig sein. So können die Bedienungshilfen des Systems beim Ansagen eines Labels genau auf ein Bildschirmelement verweisen. Diese Entsprechung informiert Nutzer, wenn sie durch die Benutzeroberfläche navigieren oder den Fokus auf ein Element verschieben, das sie bereits entdeckt haben.
Wenn Sie beispielsweise ein LazyColumn oder LazyRow haben, verwenden Sie den Modifikator semantics, um jedem Element einen eindeutigen collectionItemInfo zuzuweisen, wie im folgenden Snippet gezeigt:
MilkyWayList( modifier = Modifier .semantics { collectionInfo = CollectionInfo( rowCount = milkyWay.count(), columnCount = 1 ) } ) { milkyWay.forEachIndexed { index, text -> Text( text = text, modifier = Modifier.semantics { collectionItemInfo = CollectionItemInfo(index, 0, 0, 0) } ) } }
Weitere Informationen zu Semantikattributen für Listen und Grids finden Sie unter Listen- und Elementinformationen.
Gruppen ähnlicher Inhalte
Wenn in Ihrer App mehrere UI-Elemente angezeigt werden, die eine natürliche Gruppe bilden, z. B. Details eines Songs oder Attribute einer Nachricht, ordnen Sie diese Elemente in einem übergeordneten Container an (z. B. Column, Row oder Box). Verwenden Sie den Modifikator semantics des übergeordneten Containers, um mergeDescendants auf true festzulegen.
So können Bedienungshilfen die Inhaltsbeschreibungen der inneren Elemente nacheinander in einer einzigen Ansage präsentieren. Durch das Zusammenfassen verwandter Elemente können Nutzer von Hilfstechnologien die Informationen auf dem Bildschirm effizienter finden.
Im folgenden Snippet fungiert die Row-Komposition als übergeordneter Container.
Innerhalb des Row befinden sich zugehörige Elemente, die Metadaten für einen Blogpost enthalten – den Avatar des Autors, den Namen des Autors und die geschätzte Lesezeit.
Wenn du mergeDescendants auf true setzt, werden diese inneren Elemente gruppiert, sodass Bedienungshilfen sie als eine Einheit behandeln können.
@Composable private fun PostMetadata(metadata: Metadata) { // Merge elements below for accessibility purposes Row(modifier = Modifier.semantics(mergeDescendants = true) {}) { Image( imageVector = Icons.Filled.AccountCircle, contentDescription = null // decorative ) Column { Text(metadata.author.name) Text("${metadata.date} • ${metadata.readTimeMinutes} min read") } } }
Wenn Sie ähnliche Elemente wie im vorherigen Beispiel gruppieren, machen Sie nur den übergeordneten Container interaktiv. Fügen Sie den inneren untergeordneten Elementen keine clickable- oder focusable-Modifikatoren hinzu. Wenden Sie die Modifikatoren stattdessen auf das übergeordnete Row oder Column an.
Da Bedienungshilfen die Beschreibungen der inneren Elemente in einer einzigen Äußerung ansagen, ist es wichtig, jede Beschreibung so kurz wie möglich zu halten und gleichzeitig die Bedeutung des Elements zu vermitteln.
Hinweis:Wenn du eine Inhaltsbeschreibung für eine Gruppe erstellst, solltest du im Allgemeinen vermeiden, den Text der untergeordneten Elemente zusammenzufassen. Dadurch wird die Beschreibung der Gruppe instabil. Wenn sich der Text eines untergeordneten Elements ändert, stimmt die Beschreibung der Gruppe möglicherweise nicht mehr mit dem sichtbaren Text überein.
In einer Liste oder einem Raster kann ein Screenreader den Text der untergeordneten Textknoten eines Listen- oder Rasterelements zusammenfassen. Am besten vermeiden Sie es, diese Ankündigung zu ändern.
Weitere Informationen zur Semantik beim Zusammenführen finden Sie unter Zusammenführen und Löschen.
Überschriften im Text
In einigen Apps werden Überschriften verwendet, um Textgruppen auf dem Bildschirm zusammenzufassen. Wenn ein bestimmtes Element eine Überschrift darstellt, können Sie seinen Zweck für Bedienungshilfen angeben, indem Sie die Eigenschaft heading im Modifikator semantics festlegen.
@Composable private fun Subsection(text: String) { Text( text = text, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.semantics { heading() } ) }
Nutzer von Bedienungshilfen können zwischen Überschriften statt zwischen Absätzen oder Wörtern navigieren. Diese Flexibilität verbessert die Textnavigation.
Weitere Informationen zur Semantik-Property heading finden Sie unter Überschriften.
Titel im Bereich „Bedienungshilfen“
Unter Android 9 (API-Level 28) und höher können Sie barrierefreie Titel für die Bereiche eines Bildschirms angeben. Im Sinne der Barrierefreiheit ist ein Bereich ein visuell abgegrenzter Teil eines Fensters.
Damit Bedienungshilfen das fensterähnliche Verhalten eines Bereichs verstehen, sollten Sie den Bereichen Ihrer App aussagekräftige Titel geben. Bedienungshilfen können Nutzern dann detailliertere Informationen liefern, wenn sich das Erscheinungsbild oder der Inhalt eines Bereichs ändert.
ShareSheet( message = "Choose how to share this photo", modifier = Modifier .fillMaxWidth() .align(Alignment.TopCenter) .semantics { paneTitle = "New bottom sheet" } )
Weitere Informationen zum Semantikattribut paneTitle finden Sie unter Fensterähnliche Komponenten.
Dekorative Elemente
Wenn ein Element in Ihrer Benutzeroberfläche nur für visuelle Abstände oder die visuelle Darstellung vorhanden ist, legen Sie die entsprechenden Attribute für das Element fest, um anzugeben, dass Bedienungshilfen es ignorieren können.
Legen Sie für Image- oder Icon-Kompositionen contentDescription = null fest. Für andere rein dekorative Elemente, die keinen Kontext oder keine Funktionalität bieten, können Sie hideFromAccessibility verwenden. Diese Semantik-Property weist Bedienungshilfen an, das Element zu ignorieren.
Wenn ein interaktives Compose-Element dekorative, nicht interaktive untergeordnete Elemente enthält, verwenden Sie clearAndSetSemantics, damit Bedienungshilfen diese nicht durchlaufen. Beachten Sie, dass clearAndSetSemantics die Standardsemantik eines Elements und seiner untergeordneten Elemente vollständig löscht. So können Sie ein neues, einheitliches Element für die Barrierefreiheit im Internet definieren. Normalerweise verwenden Sie diesen Ansatz für komplexe benutzerdefinierte Komponenten.
Im folgenden Beispiel sind Icon und Text dekorative untergeordnete Elemente in einem benutzerdefinierten Schalter. Wenn du verhindern möchtest, dass Bedienungshilfen diese untergeordneten Elemente einzeln durchlaufen, kannst du ihre Semantik mit clearAndSetSemantics für das übergeordnete Row löschen. Dadurch werden Bedienungshilfen angewiesen, das gesamte Row-Element als durchlaufbare Ein/Aus-Schaltfläche zu behandeln:
// Developer might intend this to be a toggleable. // Using `clearAndSetSemantics`, on the Row, a clickable modifier is applied, // a custom description is set, and a Role is applied. @Composable fun FavoriteToggle() { val checked = remember { mutableStateOf(true) } Row( modifier = Modifier .toggleable( value = checked.value, onValueChange = { checked.value = it } ) .clearAndSetSemantics { stateDescription = if (checked.value) "Favorited" else "Not favorited" toggleableState = ToggleableState(checked.value) role = Role.Switch }, ) { Icon( imageVector = Icons.Default.Favorite, contentDescription = null // not needed here ) Text("Favorite?") } }
Weitere Informationen zum Löschen von Semantik finden Sie unter Semantik löschen und festlegen.
Aktionen für Bedienungshilfen hinzufügen
Es ist wichtig, dass Nutzer von Bedienungshilfen alle User-Flows in deiner App abschließen können.
Wenn die Interaktion mit Ihrem benutzerdefinierten Composable den Status der App auf eine nicht offensichtliche Weise ändert, geben Sie beschreibende Labels für Standard-Tippaktionen mit Parametern wie onClickLabel oder onLongClickLabel in Modifier.clickable oder Modifier.combinedClickable an.
Verwenden Sie customActions für komplexe Interaktionen, die sich nicht Standardtippaktionen zuordnen lassen.
Wenn Nutzer in Ihrer App beispielsweise ein Element an eine andere Stelle ziehen oder ein Element in einer Liste wischen können, können Sie eine alternative Möglichkeit zum Abschließen dieser Nutzerflüsse anbieten, indem Sie die Aktion für Bedienungshilfen verfügbar machen. So können Nutzer von TalkBack, Voice Access oder Schalterzugriff Aktionen ausführen, die sonst möglicherweise nur über Touch-Gesten verfügbar sind.
In Compose können Sie benutzerdefinierte Bedienungshilfenaktionen über das Attribut customActions im Modifikator semantics mit CustomAccessibilityAction definieren.
Wenn Nutzer in deiner App beispielsweise ein Element wegwischen können, um es zu schließen, kannst du diese Funktion über eine benutzerdefinierte Aktion für Bedienungshilfen verfügbar machen:
SwipeToDismissBox( modifier = Modifier.semantics { // Represents the swipe to dismiss for accessibility customActions = listOf( CustomAccessibilityAction( label = "Remove article from list", action = { removeArticle() true } ) ) }, state = rememberSwipeToDismissBoxState(), backgroundContent = {} ) { ArticleListItem() }
Wenn die benutzerdefinierte Aktion für Barrierefreiheit im Internet implementiert ist, können Nutzer über das Aktionsmenü darauf zugreifen.
Weitere Informationen zu benutzerdefinierten Aktionen finden Sie unter Benutzerdefinierte Aktionen.
Verfügbare Aktionen verständlich machen
Wenn ein UI-Element Aktionen wie „Berühren und halten“ unterstützt, wird dies von einem Bedienungshilfendienst wie TalkBack als „Doppeltippen und halten, um lange zu drücken“ angesagt.
Diese allgemeine Ansage gibt dem Nutzer keinen Kontext dazu, was eine Berühren-und-halten-Aktion bewirkt.
Geben Sie eine aussagekräftige Beschreibung für die Aktion an, um diese Ansage nützlicher zu machen.
In Compose haben Standard-Interaktionsmodifikatoren wie clickable und combinedClickable integrierte Parameter (nämlich onClickLabel und onLongClickLabel), mit denen Sie Beschreibungen für die Aktionen bereitstellen können, wie im folgenden Beispiel:
var contextMenuPhotoId by rememberSaveable { mutableStateOf<Int?>(null) } val haptics = LocalHapticFeedback.current LazyVerticalGrid(columns = GridCells.Adaptive(minSize = 128.dp)) { items(photos, { it.id }) { photo -> ImageItem( photo, Modifier .combinedClickable( onClick = { activePhotoId = photo.id }, onLongClick = { haptics.performHapticFeedback(HapticFeedbackType.LongPress) contextMenuPhotoId = photo.id }, onLongClickLabel = stringResource(R.string.open_context_menu) ) ) } } if (contextMenuPhotoId != null) { PhotoActionsSheet( photo = photos.first { it.id == contextMenuPhotoId }, onDismissSheet = { contextMenuPhotoId = null } ) }
TalkBack sagt dann „Kontextmenü öffnen“ an, damit Nutzer den Zweck der Aktion verstehen.
Sie können ein Label auch direkt im semantics-Modifikator angeben.
Weitere Informationen zum Reagieren auf Tipp- und Klickgesten findest du unter Tippen und Drücken und Interaktive Elemente.
Integrierte Bedienungshilfen verwenden
Nutze beim Entwerfen der Benutzeroberfläche deiner App die integrierten Bedienungshilfen, um zu vermeiden, dass du bereits vorhandene Funktionen neu implementierst. Material, Compose UI und Foundation APIs implementieren und bieten standardmäßig viele Bedienungshilfen.
Verwenden Sie in Jetpack Compose integrierte Composables wie Button, Switch und Checkbox, um barrierefreie Benutzeroberflächen zu erstellen. Diese Komponenten enthalten vordefinierte semantics-Modifikatoren wie role und stateDescription, mit denen Sie die Barrierefreiheit Ihrer Apps verbessern können.
Semantik auf benutzerdefinierte Komponenten anwenden
Achten Sie beim Erstellen einer benutzerdefinierten Komponente darauf, welche Art von Unterstützung für die Barrierefreiheit im Internet diese Komponente benötigt, um ihre Rolle zu erfüllen. Häufig reichen die Standard-Compose APIs aus, die Sie bereits verwenden, z. B. clickable, toggleable oder selectable, da sie die Semantikstruktur automatisch für Sie füllen.
Einige Komponenten erfordern jedoch spezifischere Informationen, als Standardmodifikatoren bieten. Suchen Sie in diesen Fällen nach speziellen Modifikatoren (z. B. triStateToggleable) oder geben Sie, falls keine vorhanden sind, die Semantik explizit mit dem Low-Level-Modifikator Modifier.semantics an.
Betrachten wir beispielsweise einen TriStateSwitch, einen Schalter mit drei Zuständen (Ein, Aus und Unbestimmt).
Während ein Standard-toggleable-Modifikator zwei Zustände annimmt, verarbeitet der triStateToggleable-Modifikator die Komplexität des dritten Zustands. Die Bedienungshilfen Role (Switch) und State werden automatisch festgelegt. So erhalten Bedienungshilfen genaue Informationen und Sie müssen die Semantik nicht manuell definieren.
Das folgende Code-Snippet zeigt eine TriStateSwitch, die diesen Ansatz verwendet:
@Composable fun TriStateSwitch( state: ToggleableState, onClick: () -> Unit, modifier: Modifier = Modifier ) { // A real implementation would include custom drawing for the switch. // This example uses a Box to demonstrate the semantics. Box( modifier = modifier .size(width = 64.dp, height = 40.dp) // triStateToggleable handles the semantics (Role and State) // automatically, so explicit Modifier.semantics is not needed here. .triStateToggleable( state = state, onClick = onClick, role = Role.Switch ) // Add visual feedback based on the state .background( when (state) { ToggleableState.On -> Color.Green ToggleableState.Off -> Color.Gray ToggleableState.Indeterminate -> Color.Yellow } ) ) } // Usage within another composable: var state by remember { mutableStateOf(ToggleableState.Off) } TriStateSwitch( state = state, onClick = { state = when (state) { ToggleableState.Off -> ToggleableState.Indeterminate ToggleableState.Indeterminate -> ToggleableState.On ToggleableState.On -> ToggleableState.Off } } )
Achten Sie beim Erstellen einer benutzerdefinierten Komponente darauf, alle relevanten semantischen Eigenschaften für die Barrierefreiheit anzugeben. Wenn Ihre Komponente beispielsweise ein Standardsteuerelement wie einen Schalter oder eine Schaltfläche nachahmt, umfassen diese Eigenschaften die Rolle der Komponente (z. B. Role.Switch oder Role.Button), stateDescription (z. B. „Ein“, „Aus“, „Ausgewählt“ oder „Nicht ausgewählt“) und alle relevanten Aktionslabels. Weitere Informationen finden Sie unter Benutzerdefinierte Komponenten.
Andere Hinweise als Farbe verwenden
Verwende zur Unterstützung von Nutzern mit Farbsehschwäche andere Hinweise als Farben, um UI-Elemente auf den Bildschirmen deiner App zu unterscheiden. Dazu können verschiedene Formen oder Größen, Text oder visuelle Muster oder Audio- oder haptisches Feedback gehören, um die Unterschiede zwischen den Elementen zu kennzeichnen.
Abbildung 1 zeigt zwei Versionen einer Aktivität. In einer Version wird nur Farbe verwendet, um zwischen zwei möglichen Aktionen in einem Workflow zu unterscheiden. Die andere Version verwendet die Best Practice, zusätzlich zu Farben auch Formen und Text zu verwenden, um die Unterschiede zwischen den beiden Optionen hervorzuheben:
Medieninhalte barrierefreier gestalten
Wenn du eine App mit Medieninhalten wie einem Videoclip oder einer Audioaufnahme entwickelst, solltest du versuchen, Nutzern mit unterschiedlichen Arten von Barrierefreiheitsanforderungen das Verständnis des Materials zu erleichtern. Versuchen Sie insbesondere Folgendes:
- Biete Steuerelemente an, mit denen Nutzer die Medien pausieren oder stoppen, die Lautstärke ändern und Untertitel ein- oder ausschalten können.
- Wenn ein Video Informationen enthält, die für die Durchführung eines Workflows wichtig sind, stelle dieselben Inhalte in einem alternativen Format bereit, z. B. als Transkript.
Zusätzliche Ressourcen
Weitere Informationen dazu, wie du deine App barrierefreier gestalten kannst, findest du in den folgenden zusätzlichen Ressourcen: