Wenn Bedienungshilfen durch Elemente auf dem Bildschirm navigieren, ist es wichtig, dass diese Elemente mit dem richtigen Detaillierungsgrad gruppiert, getrennt oder sogar ausgeblendet werden. Wenn jedes einzelne Low-Level-Composable auf dem Bildschirm unabhängig hervorgehoben wird, müssen Nutzer viel interagieren, um sich auf dem Bildschirm zu bewegen. Wenn Elemente zu stark miteinander verschmelzen, ist für Nutzer möglicherweise nicht klar, welche Elemente logisch zusammengehören. Wenn es auf dem Bildschirm Elemente gibt, die rein dekorativ sind, können diese für Bedienungshilfen ausgeblendet werden. In diesen Fällen können Sie Compose APIs verwenden, um Semantik zusammenzuführen, zu löschen und auszublenden.
Merge-Semantik
Wenn du einen clickable-Modifikator auf eine übergeordnete zusammensetzbare Funktion anwendest, führt Compose automatisch alle untergeordneten Elemente zusammen. Informationen dazu, wie interaktive Compose Material- und Foundation-Komponenten standardmäßig Zusammenführungsstrategien verwenden, finden Sie im Abschnitt Interaktive Elemente.
Es ist üblich, dass eine Komponente aus mehreren Composables besteht. Diese Composables könnten eine logische Gruppe bilden und jeweils wichtige Informationen enthalten, aber Sie möchten möglicherweise, dass Bedienungshilfen sie als ein Element betrachten.
Stellen Sie sich beispielsweise eine zusammensetzbare Funktion vor, die den Avatar, den Namen und einige zusätzliche Informationen eines Nutzers anzeigt:
Sie können Compose aktivieren, um diese Elemente zusammenzuführen, indem Sie den Parameter mergeDescendants im Semantikmodifikator verwenden. So behandeln Bedienungshilfen die Komponente als eine Entität und alle semantischen Eigenschaften der Nachfolger werden zusammengeführt:
@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") } } }
Bedienungshilfen konzentrieren sich jetzt auf den gesamten Container und führen dessen Inhalte zusammen:

Für jedes Semantikattribut ist eine Zusammenführungsstrategie definiert. Mit dem Attribut ContentDescription werden beispielsweise alle untergeordneten ContentDescription-Werte einer Liste hinzugefügt. Sie können die Zusammenführungsstrategie einer Semantik-Property prüfen, indem Sie sich die mergePolicy-Implementierung in SemanticsProperties.kt ansehen.
Attribute können den Wert des übergeordneten oder untergeordneten Elements annehmen, die Werte in einer Liste oder einem String zusammenführen, die Zusammenführung überhaupt nicht zulassen und stattdessen eine Ausnahme auslösen oder eine andere benutzerdefinierte Zusammenführungsstrategie verwenden.
Es gibt andere Szenarien, in denen Sie erwarten, dass die Semantik von untergeordneten Elementen mit der Semantik eines übergeordneten Elements zusammengeführt wird, dies aber nicht geschieht. Im folgenden Beispiel haben wir ein übergeordnetes clickable-Listenelement mit untergeordneten Elementen. Wir erwarten, dass das übergeordnete Element alle untergeordneten Elemente zusammenführt:
@Composable private fun ArticleListItem( openArticle: () -> Unit, addToBookmarks: () -> Unit, ) { Row(modifier = Modifier.clickable { openArticle() }) { // Merges with parent clickable: Icon( painter = painterResource(R.drawable.ic_logo), contentDescription = "Article thumbnail" ) ArticleDetails() // Defies the merge due to its own clickable: BookmarkButton(onClick = addToBookmarks) } }
Wenn der Nutzer auf das Element clickable Row drückt, wird der Artikel geöffnet. Darin befindet sich ein BookmarkButton, um den Artikel als Lesezeichen zu speichern. Diese verschachtelte Schaltfläche wird als nicht zusammengeführt angezeigt, während der Rest der untergeordneten Inhalte in der Zeile zusammengeführt wird:
Row. Der nicht zusammengeführte Baum enthält separate Knoten für jede Text zusammensetzbare Funktion.Einige Composables werden absichtlich nicht automatisch unter einem übergeordneten Element zusammengeführt. Ein übergeordnetes Element kann seine untergeordneten Elemente nicht zusammenführen, wenn die untergeordneten Elemente ebenfalls zusammengeführt werden, entweder durch explizites Festlegen von mergeDescendants = true oder durch Komponenten, die sich selbst zusammenführen, z. B. Schaltflächen oder anklickbare Elemente. Wenn Sie wissen, wie bestimmte APIs zusammengeführt werden oder die Zusammenführung verhindern, können Sie potenzielle unerwartete Verhaltensweisen beheben.
Verwenden Sie die Zusammenführung, wenn untergeordnete Elemente eine logische und sinnvolle Gruppe unter ihrem übergeordneten Element bilden. Wenn die verschachtelten untergeordneten Elemente jedoch manuell angepasst oder ihre eigene Semantik entfernt werden muss, sind andere APIs möglicherweise besser für Ihre Anforderungen geeignet (z. B. clearAndSetSemantics).
Semantik löschen und festlegen
Wenn semantische Informationen vollständig gelöscht oder überschrieben werden müssen, ist clearAndSetSemantics eine leistungsstarke API.
Wenn die Semantik einer Komponente und ihrer untergeordneten Elemente gelöscht werden muss, verwenden Sie diese API mit einem leeren Lambda. Wenn die Semantik überschrieben werden muss, fügen Sie den neuen Inhalt in das Lambda ein.
Wenn Sie die Semantik mit einem leeren Lambda löschen, wird die gelöschte Semantik nicht an Nutzer gesendet, die diese Informationen verwenden, z. B. für Bedienungshilfen, Autofill oder Tests. Wenn Inhalte mit clearAndSetSemantics{/*semantic information*/} überschrieben werden, ersetzen die neuen Semantiken alle vorherigen Semantiken des Elements und seiner untergeordneten Elemente.
Das folgende Beispiel zeigt eine benutzerdefinierte Ein/Aus-Komponente, die durch eine interaktive Zeile mit einem Symbol und Text dargestellt wird:
// 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?") } }
Obwohl das Symbol und der Text einige semantische Informationen enthalten, weisen sie zusammen nicht darauf hin, dass diese Komponente umschaltbar ist. Das Zusammenführen reicht nicht aus, da Sie zusätzliche Informationen zur Komponente angeben müssen.
Da mit dem obigen Snippet eine benutzerdefinierte Ein/Aus-Schaltfläche erstellt wird, müssen Sie die Ein/Aus-Funktion sowie die Semantik stateDescription, toggleableState und role hinzufügen. So sind der Komponentenstatus und die zugehörige Aktion verfügbar. TalkBack sagt dann beispielsweise „Zum Umschalten doppeltippen“ statt „Zum Aktivieren doppeltippen“ an.
Durch das Löschen der ursprünglichen Semantik und das Festlegen einer neuen, aussagekräftigeren Semantik können Bedienungshilfen jetzt erkennen, dass es sich um eine umschaltbare Komponente handelt, die den Status wechseln kann.
Beachten Sie bei der Verwendung von clearAndSetSemantics Folgendes:
- Da Dienste keine Informationen erhalten, wenn diese API festgelegt ist, sollten Sie sie nur sparsam verwenden.
- Semantische Informationen können potenziell von KI-Agenten und ähnlichen Diensten verwendet werden, um den Bildschirm zu verstehen. Sie sollten daher nur bei Bedarf gelöscht werden.
- Benutzerdefinierte Semantik kann innerhalb des API-Lambdas festgelegt werden.
- Die Reihenfolge der Modifikatoren ist wichtig. Diese API löscht alle Semantiken, die nach der Anwendung der API auftreten, unabhängig von anderen Zusammenführungsstrategien.
Semantik ausblenden
In einigen Szenarien müssen Elemente nicht an Bedienungshilfen gesendet werden, z. B. wenn ihre zusätzlichen Informationen für die Bedienungshilfe redundant sind oder sie rein visuell dekorativ und nicht interaktiv sind. In diesen Fällen können Sie Elemente mit der hideFromAccessibility API ausblenden.
In den folgenden Beispielen sind Komponenten aufgeführt, die möglicherweise ausgeblendet werden müssen: ein redundantes Wasserzeichen, das sich über eine Komponente erstreckt, und ein Zeichen, das zur dekorativen Trennung von Informationen verwendet wird.
@Composable fun WatermarkExample( watermarkText: String, content: @Composable () -> Unit, ) { Box { WatermarkedContent() // Mark the watermark as hidden to accessibility services. WatermarkText( text = watermarkText, color = Color.Gray.copy(alpha = 0.5f), modifier = Modifier .align(Alignment.BottomEnd) .semantics { hideFromAccessibility() } ) } } @Composable fun DecorativeExample() { Text( modifier = Modifier.semantics { hideFromAccessibility() }, text = "A dot character that is used to decoratively separate information, like •" ) }
Wenn Sie hier hideFromAccessibility verwenden, werden das Wasserzeichen und die Dekoration vor Bedienungshilfen verborgen, behalten aber ihre Semantik für andere Anwendungsfälle wie Tests.
Anwendungsfälle nach Kategorie
Im Folgenden finden Sie eine Zusammenfassung der Anwendungsfälle, um die vorherigen APIs klar voneinander zu unterscheiden:
- Wenn Inhalte nicht für Bedienungshilfen vorgesehen sind:
- Verwenden Sie
hideFromAccessibility, wenn Inhalte möglicherweise dekorativ oder redundant sind, aber dennoch getestet werden müssen. - Verwenden Sie
clearAndSetSemantics{}mit einem leeren Lambda, wenn die Semantik für übergeordnete und untergeordnete Elemente für alle Dienste gelöscht werden muss. - Verwenden Sie
clearAndSetSemantics{/*content*/}mit Inhalten innerhalb des Lambda-Ausdrucks, wenn die Semantik einer Komponente manuell festgelegt werden muss.
- Verwenden Sie
- Wenn Inhalte als eine Einheit behandelt werden sollen und alle Informationen der untergeordneten Elemente erforderlich sind, um vollständig zu sein:
- Semantische Nachfolger zusammenführen.
Empfehlungen für Sie
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Barrierefreiheit in Compose
- [Material Design 2 in Compose][19]
- Compose-Layout testen