Um Nutzern mit Beeinträchtigungen zu helfen, können Sie mit dem Android-Framework eine Bedienungshilfe erstellen, die Inhalte aus Apps für Nutzer präsentieren und Apps in ihrem Namen bedienen kann.
Android bietet mehrere Systemdienste für Barrierefreiheit, darunter die folgenden:
- TalkBack: Diese Funktion hilft Menschen mit Sehbehinderung oder eingeschränktem Sehvermögen. Es kündigt Inhalte über eine synthetische Stimme an und führt Aktionen in einer App als Reaktion auf Nutzergesten aus.
- Schalterzugriff: Diese Funktion ist für Menschen mit motorischen Beeinträchtigungen hilfreich. Es werden interaktive Elemente hervorgehoben und Aktionen ausgeführt, wenn der Nutzer eine Taste drückt. Das Gerät lässt sich über einen oder zwei Tasten steuern.
Damit Menschen mit Behinderung Ihre App problemlos nutzen können, muss sie den Best Practices auf dieser Seite entsprechen. Diese basieren auf den Richtlinien unter Apps barrierefreier gestalten.
Jede dieser Best Practices, die in den folgenden Abschnitten beschrieben werden, kann die Barrierefreiheit Ihrer App weiter verbessern:
- Elemente mit Labels versehen
- 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
- Wenn Sie Bedienungshilfen hinzufügen, können Nutzer von Bedienungshilfen wichtige Nutzerabläufe in Ihrer App ausführen.
- Integrierte Bedienungshilfen verwenden
- Compose bietet standardmäßig viele Bedienungshilfen. Nutzen Sie vordefinierte Barrierefreiheitsfunktionen, um Ihre Komponenten mit wenig oder gar keinem zusätzlichen Aufwand barrierefrei zu gestalten. Compose bietet auch Möglichkeiten, spezifischere Anforderungen an die Barrierefreiheit zu unterstützen, die nicht von den Standardfunktionen abgedeckt werden.
- Andere Hinweise als Farbe verwenden
- Nutzer müssen in einer Benutzeroberfläche klar zwischen den verschiedenen Elementkategorien unterscheiden können. Verwenden Sie dazu Muster und Positionen sowie Farben, um diese Unterschiede darzustellen.
- Medieninhalte barrierefreier gestalten
- Fügen Sie den Video- oder Audioinhalten Ihrer App Beschreibungen hinzu, damit Nutzer, die diese Inhalte ansehen oder anhören, nicht nur auf visuelle oder akustische Hinweise angewiesen sind.
Labelelemente
Es ist wichtig, Nutzern für jedes interaktive UI-Element in Ihrer App nützliche und aussagekräftige 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 Nutzern vorlesen.
In den meisten Fällen bieten Compose APIs und Material standardmäßige Unterstützung für Barrierefreiheit. Wenn Sie die semantischen Eigenschaften eines UI-Elements jedoch manuell angeben müssen, verwenden Sie den Modifier semantics und die Property contentDescription. Weitere Informationen zur Semantik finden Sie unter Semantik.
In den folgenden Abschnitten werden verschiedene andere Labeling-Techniken beschrieben.
Bearbeitbare Elemente
Wenn Sie bearbeitbare Elemente wie Textfelder kennzeichnen, ist es hilfreich, neben dem Beispieltext, der für Screenreader verfügbar ist, auch Text anzuzeigen, der ein Beispiel für eine gültige Eingabe im Element selbst enthält. In diesen Fällen können Sie Platzhaltertext (auch als Hinweistext bezeichnet) verwenden.
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") } )
Häufig hat ein Textfeld auch ein entsprechendes beschreibendes Label, das angibt, was Nutzer eingeben müssen.
Im folgenden Beispiel hat TextField einen label-Parameter, der eine Beschreibung der Barrierefreiheit 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 Ausgeben eines Labels auf genau ein Element auf dem Bildschirm verweisen. So wissen Nutzer, wann sie durch die Benutzeroberfläche navigieren oder den Fokus auf ein Element legen, das sie bereits entdeckt haben.
Wenn Sie beispielsweise ein LazyColumn- oder LazyRow-Element haben, verwenden Sie den Modifikator semantics, um jedem Element eine eindeutige 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 semantischen Eigenschaften für Listen und Tabellen 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 zu einem Song oder Attribute einer Nachricht, ordnen Sie diese Elemente in einem übergeordneten Container an (z. B. Column, Row oder Box). Verwenden Sie den semantics-Modifikator 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 ähnlicher Elemente können Nutzer von Hilfstechnologien die Informationen auf dem Bildschirm effizienter erfassen.
Im folgenden Snippet fungiert die zusammensetzbare Funktion Row als übergeordneter Container.
Innerhalb von Row befinden sich zugehörige Elemente, die Metadaten für einen Blogbeitrag enthalten, z. B. das Avatar des Autors, der Name des Autors und die geschätzte Lesezeit.
Wenn Sie mergeDescendants auf true setzen, werden diese inneren Elemente gruppiert, sodass sie von Barrierefreiheitsdiensten als eine Einheit behandelt werden 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 zusammengehörige Elemente wie im vorherigen Beispiel gruppieren, machen Sie nur den übergeordneten Container interaktiv. Fügen Sie den inneren untergeordneten Elementen keine clickable- oder focusable-Modifizierer hinzu. Wenden Sie die Modifizierer stattdessen auf das übergeordnete Row oder Column an.
Da Barrierefreiheitsdienste die Beschreibungen der inneren Elemente in einem einzigen Satz ausgeben, 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 beim Erstellen einer Inhaltsbeschreibung für eine Gruppe vermeiden, den Text der untergeordneten Elemente zusammenzufassen. Dadurch wird die Beschreibung der Gruppe anfällig. 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. Es ist am besten, diese Mitteilung nicht zu ändern.
Weitere Informationen zum Zusammenführen von Semantik finden Sie unter Zusammenführen und Bereinigen.
Überschriften im Text
Einige Apps verwenden Überschriften, um Textgruppen auf dem Bildschirm zusammenzufassen. Wenn ein bestimmtes Element eine Überschrift darstellt, können Sie seinen Zweck für Barrierefreiheitsdienste 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 wählen, ob sie zwischen Überschriften statt zwischen Absätzen oder Wörtern navigieren möchten. Diese Flexibilität verbessert die Textnavigation.
Weitere Informationen zum semantischen Attribut heading finden Sie unter Überschriften.
Titel von Bedienungshilfenbereichen
Unter Android 9 (API-Level 28) und höher können Sie barrierefreie Titel für die Bereiche eines Bildschirms angeben. Aus Gründen der Barrierefreiheit ist ein Bereich ein visuell abgegrenzter Teil eines Fensters.
Damit Bedienungshilfen das fensterähnliche Verhalten eines Bereichs nachvollziehen können, sollten Sie den Bereichen Ihrer App aussagekräftige Titel geben. Barrierefreiheitsdienste 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 Attribut paneTitle semantics finden Sie unter Fensterähnliche Komponenten.
Dekorative Elemente
Wenn ein Element in Ihrer Benutzeroberfläche nur zur visuellen Abstandsgestaltung oder zur visuellen Darstellung dient, legen Sie die entsprechenden Eigenschaften für das Element fest, um anzugeben, dass es von Barrierefreiheitsdiensten ignoriert werden kann.
Legen Sie für Image- oder Icon-Composables contentDescription = null fest. Für andere rein dekorative Elemente, die keinen Kontext oder keine Funktion bieten, können Sie hideFromAccessibility verwenden. Diese semantische Eigenschaft weist Bedienungshilfen an, das Element zu ignorieren.
Wenn ein interaktives Composable dekorative, nicht interaktive untergeordnete Elemente enthält, verwenden Sie clearAndSetSemantics, um sicherzustellen, dass Bedienungshilfen sie 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 Barrierefreiheitselement 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. Damit die Bedienungshilfen diese untergeordneten Elemente nicht einzeln durchlaufen, können Sie ihre Semantik mit clearAndSetSemantics für das übergeordnete Row löschen. Bedienungshilfen werden so angewiesen, das gesamte Row als durchlaufbaren Schalter 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 Nutzerabläufe in Ihrer App durchlaufen können.
Wenn durch die Interaktion mit Ihrem benutzerdefinierten Composable der Status der App auf eine Weise geändert wird, die nicht offensichtlich ist, stellen Sie beschreibende Labels für Standard-Tippaktionen bereit. Verwenden Sie dazu Parameter wie onClickLabel oder onLongClickLabel in Modifier.clickable oder Modifier.combinedClickable.
Verwenden Sie für komplexe Interaktionen, die nicht Standard-Taps zugeordnet werden können, customActions.
Wenn Nutzer in Ihrer App beispielsweise ein Element an einen anderen Ort ziehen oder in einer Liste auf ein Element wischen können, können Sie eine alternative Möglichkeit zum Ausführen dieser Nutzeraktionen anbieten, indem Sie die Aktion für Barrierefreiheitsdienste verfügbar machen. So können Nutzer von TalkBack, Voice Access oder Schalterzugriff Aktionen ausführen, die sonst möglicherweise nur über Touch-Gesten möglich sind.
In Compose können Sie benutzerdefinierte Barrierefreiheitsaktionen über die customActions-Property im semantics-Modifikator mit CustomAccessibilityAction definieren.
Wenn Nutzer in Ihrer App beispielsweise ein Element durch Wischen schließen können, können Sie die Funktion über eine benutzerdefinierte Bedienungshilfeaktion 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() }
Nachdem die benutzerdefinierte Bedienungshilfe implementiert wurde, können Nutzer über das Aktionsmenü darauf zugreifen.
Weitere Informationen zu benutzerdefinierten Aktionen
Verfügbare Aktionen verständlich machen
Wenn ein UI-Element Aktionen wie „Berühren und halten“ unterstützt, wird es von einem Bedienungshilfendienst wie TalkBack als „Doppeltippen und Halten zum langen Drücken“ angekündigt.
Diese allgemeine Ankündigung gibt dem Nutzer keinen Kontext dazu, was eine Touch-and-Hold-Aktion bewirkt.
Geben Sie eine aussagekräftige Beschreibung für die Aktion an, damit die Benachrichtigung nützlicher ist.
In Compose haben Standard-Interaktionsmodifizierer wie clickable und combinedClickable integrierte Parameter (onClickLabel und onLongClickLabel), mit denen Sie Beschreibungen für die Aktionen angeben 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 gibt dann „Kontextmenü öffnen“ aus, damit Nutzer den Zweck der Aktion besser verstehen.
Sie können auch direkt im semantics-Modifikator ein Label angeben.
Weitere Informationen zum Reagieren auf Tippen und Klicken finden Sie unter Tippen und Drücken und Interaktive Elemente.
Integrierte Bedienungshilfen verwenden
Nutzen Sie beim Entwerfen der Benutzeroberfläche Ihrer App integrierte Bedienungshilfen, um zu vermeiden, dass Sie bereits vorhandene Funktionen neu implementieren müssen. Material-, Compose UI- und Foundation-APIs implementieren und bieten standardmäßig viele barrierefreie Funktionen.
Verwenden Sie in Jetpack Compose integrierte Composables wie Button, Switch und Checkbox, um barrierefreie UIs zu erstellen. Diese Komponenten sind bereits mit semantics-Modifizierern wie role und stateDescription ausgestattet, 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 Barrierefreiheitsunterstützung diese Komponente benötigt, um ihre Rolle zu erfüllen. Häufig reichen die standardmäßigen Compose-APIs, die Sie bereits verwenden, z. B. clickable, toggleable oder selectable, aus, da sie den semantischen Baum automatisch für Sie erstellen.
Für einige Komponenten sind jedoch genauere Informationen erforderlich, als mit Standardmodifikatoren bereitgestellt werden. Suchen Sie in diesen Fällen nach speziellen Modifikatoren wie triStateToggleable oder geben Sie, falls keine vorhanden sind, explizit Semantik mit dem Low-Level-Modifikator Modifier.semantics an.
Betrachten Sie beispielsweise einen TriStateSwitch, einen Schalter mit drei Zuständen („Ein“, „Aus“ und „Unbestimmt“).
Bei einem Standard-toggleable-Modifikator werden zwei Status angenommen, während der triStateToggleable-Modifikator die Komplexität des dritten Status berücksichtigt. Die Barrierefreiheit 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 ein TriStateSwitch, das 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 } } )
Wenn Sie eine benutzerdefinierte Komponente erstellen, müssen Sie alle relevanten semantischen Eigenschaften für die Barrierefreiheit angeben. Wenn Ihre Komponente beispielsweise ein Standardsteuerelement wie einen Schalter oder eine Schaltfläche imitiert, enthalten diese Eigenschaften die Rolle der Komponente (z. B. Role.Switch oder Role.Button), stateDescription (z. B. „Ein“, „Aus“, „Aktiviert“ oder „Nicht aktiviert“) und alle relevanten Aktionslabels. Weitere Informationen finden Sie unter Benutzerdefinierte Komponenten.
Andere Hinweise als Farbe verwenden
Verwenden Sie zur Unterstützung von Nutzern mit Farbsehschwäche andere Hinweise als Farben, um UI-Elemente auf den Bildschirmen Ihrer App zu unterscheiden. Dazu können Sie verschiedene Formen oder Größen verwenden, Text oder visuelle Muster einfügen oder akustisches oder berührungsbasiertes (haptisches) Feedback hinzufügen, 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. In der anderen Version wird zusätzlich zur Farbe auch Form und Text verwendet, um die Unterschiede zwischen den beiden Optionen hervorzuheben:
Media-Inhalte barrierefreier gestalten
Wenn Sie eine App entwickeln, die Medieninhalte wie einen Videoclip oder eine Audioaufnahme enthält, sollten Sie Nutzern mit unterschiedlichen Arten von Barrierefreiheitsanforderungen helfen, das Material zu verstehen. Versuchen Sie insbesondere Folgendes:
- Fügen Sie Steuerelemente hinzu, mit denen Nutzer die Medien pausieren oder beenden, die Lautstärke ändern und Untertitel ein- oder ausschalten können.
- Wenn in einem Video Informationen präsentiert werden, die für die Durchführung eines Arbeitsablaufs unerlässlich sind, stellen Sie dieselben Inhalte in einem alternativen Format wie einem Transkript zur Verfügung.
Zusätzliche Ressourcen
Weitere Informationen dazu, wie Sie Ihre App barrierefreier gestalten können, finden Sie in den folgenden zusätzlichen Ressourcen: