Standardmäßig ist das Verhalten des Screenreaders als Bedienungshilfe in einer App zum Schreiben von Texten implementiert
in der erwarteten Lesereihenfolge, also von links nach rechts und dann von oben nach unten.
Es gibt jedoch einige Arten von App-Layouts, bei denen der Algorithmus
Lesereihenfolge ändern,
ohne zusätzliche Hinweise. In aufrufbasierten Apps haben Sie folgende Möglichkeiten:
Beheben Sie solche Probleme mit den Properties traversalBefore
und traversalAfter
.
Seit Composer 1.5 bietet Compose eine genauso flexible API mit
konzeptionelles Modell an.
isTraversalGroup
und traversalIndex
sind semantische Attribute, die
können Sie die Bedienungshilfen und die Fokusreihenfolge von TalkBack in Szenarien steuern, in denen die
Standardsortieralgorithmus nicht geeignet ist. isTraversalGroup
identifiziert
semantisch wichtige Gruppen, während traversalIndex
die Reihenfolge der
einzelne Elemente innerhalb dieser Gruppen. Sie können nur isTraversalGroup
verwenden,
oder mit traversalIndex
für weitere Anpassungen.
Verwenden Sie isTraversalGroup
und traversalIndex
in Ihrem
App zur Steuerung der Durchquerungsreihenfolge für Screenreader.
Elemente mit isTraversalGroup
gruppieren
isTraversalGroup
ist ein boolesches Attribut, das definiert, ob eine Semantik
Knoten ist eine Durchlaufgruppe. Diese Art von Knoten ist
ein Knoten, dessen Funktion darin besteht,
als Begrenzung oder Grenze bei der Organisation der untergeordneten Knoten des Knotens.
Wenn Sie isTraversalGroup = true
für einen Knoten festlegen, werden alle untergeordneten Elemente dieses Knotens
bevor Sie zu anderen Elementen wechseln. Du kannst isTraversalGroup
festlegen auf
Fokussierbare Knoten ohne Screenreader, z. B. Spalten, Zeilen oder Felder.
Im folgenden Beispiel wird isTraversalGroup
verwendet. Es werden vier Textelemente ausgegeben. Die
Die beiden linken Elemente gehören zu einem CardBox
-Element, während die beiden rechten
zu einem anderen CardBox
-Element gehören:
// CardBox() function takes in top and bottom sample text. @Composable fun CardBox( topSampleText: String, bottomSampleText: String, modifier: Modifier = Modifier ) { Box(modifier) { Column { Text(topSampleText) Text(bottomSampleText) } } } @Composable fun TraversalGroupDemo() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is " val bottomSampleText2 = "on the right." Row { CardBox( topSampleText1, bottomSampleText1 ) CardBox( topSampleText2, bottomSampleText2 ) } }
Die Ausgabe des Codes sieht in etwa so aus:
<ph type="x-smartling-placeholder">Da keine Semantik festgelegt wurde, ist das Standardverhalten des Screenreaders um Elemente von links nach rechts und von oben nach unten zu durchqueren. Aus diesem Grund Standardmäßig werden die Satzfragmente von TalkBack in der falschen Reihenfolge vorgelesen:
„Dieser Satz ist auf“ → „Dieser Satz ist“ → „die linke Spalte“. → "auf der richtig.“
Um die Fragmente richtig zu ordnen, ändern Sie das ursprüngliche Snippet,
isTraversalGroup
in true
:
@Composable fun TraversalGroupDemo2() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is" val bottomSampleText2 = "on the right." Row { CardBox( // 1, topSampleText1, bottomSampleText1, Modifier.semantics { isTraversalGroup = true } ) CardBox( // 2, topSampleText2, bottomSampleText2, Modifier.semantics { isTraversalGroup = true } ) } }
Da isTraversalGroup
speziell für jede CardBox
festgelegt wird, ist die CardBox
-Grenzen gelten beim Sortieren ihrer Elemente. In diesem Fall ist die linke
Zuerst wird CardBox
gelesen, gefolgt vom rechten CardBox
.
Jetzt liest TalkBack die Satzfragmente in der richtigen Reihenfolge vor:
„Dieser Satz ist auf“ → „die linke Spalte“. → „Dieser Satz ist“ → "auf der richtig.“
Durchlaufreihenfolge weiter anpassen
traversalIndex
ist eine Float-Eigenschaft, mit der Sie TalkBack anpassen können
Durchlaufreihenfolge festlegen. Wenn das Gruppieren von Elementen für TalkBack nicht ausreicht,
ordnungsgemäß funktionieren, verwenden Sie traversalIndex
in Verbindung mit
isTraversalGroup
, um die Reihenfolge der Screenreader weiter anzupassen.
Das Attribut traversalIndex
hat die folgenden Eigenschaften:
- Elemente mit niedrigeren
traversalIndex
-Werten haben Vorrang. - Kann positiv oder negativ sein.
- Der Standardwert ist
0f
. - Betrifft nur Screenreader-fokussierbare Knoten, z. B. Bildschirmelemente wie
Text oder Schaltflächen. Wenn Sie beispielsweise nur
traversalIndex
für eine Spalte festlegen, haben keine Auswirkungen, es sei denn, für die Spalte wurde auchisTraversalGroup
festgelegt.
Das folgende Beispiel zeigt, wie Sie traversalIndex
und
isTraversalGroup
zusammen.
Beispiel: Ziffernblatt durchlaufen
Bei einem Ziffernblatt handelt es sich um ein häufiges Szenario, in dem arbeiten. Das Beispiel in diesem Abschnitt ist eine Zeitauswahl, Ziffernblatt durchsehen und Ziffern für die Stunde und die Minute auswählen Slots.
<ph type="x-smartling-placeholder">Im folgenden vereinfachten Snippet gibt es ein CircularLayout
, in dem 12
Es werden Zahlen gezeichnet, die bei 12 beginnen und sich im Uhrzeigersinn um den Kreis bewegen:
@Composable fun ClockFaceDemo() { CircularLayout { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier) { Text((if (value == 0) 12 else value).toString()) } }
Da die Uhranzeige mit der Standardeinstellung von links nach rechts und Reihenfolge von oben nach unten verwendet, liest TalkBack die Zahlen in der falschen Reihenfolge vor. Um das Problem zu beheben verwenden Sie den inkrementellen Zählerwert, wie im folgenden Snippet gezeigt:
@Composable fun ClockFaceDemo() { CircularLayout(Modifier.semantics { isTraversalGroup = true }) { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) { Text((if (value == 0) 12 else value).toString()) } }
Um die Durchlaufreihenfolge richtig festzulegen, legen Sie zuerst den CircularLayout
als
Durchlaufgruppe und legen Sie isTraversalGroup = true
fest. Da jeder Ziffernblatt-Text
auf das Layout gezeichnet haben, legen Sie die entsprechende traversalIndex
auf den Zähler fest.
Wert.
Da der Zählerwert kontinuierlich ansteigt,
traversalIndex
ist größer, da Zahlen zum Bildschirm hinzugefügt werden – der Uhrwert 0
hat einen traversalIndex
von 0 und der Uhrwert 1 hat den traversalIndex
von 1.
Auf diese Weise wird die Reihenfolge festgelegt, in der TalkBack vorliest. Die Zahlen
innerhalb der CircularLayout
in der erwarteten Reihenfolge gelesen werden.
Da die festgelegten traversalIndexes
nur relativ zu anderen
innerhalb derselben Gruppierung besteht, ist der Rest der Bildschirmreihenfolge
beibehalten werden. Mit anderen Worten, die im vorstehenden Code dargestellten semantischen Änderungen
das Snippet nur die Reihenfolge innerhalb der Uhranzeige ändert,
isTraversalGroup = true
festgelegt.
Hinweis: Wenn Sie die Semantik von CircularLayout's
nicht auf isTraversalGroup =
true
festlegen, werden die traversalIndex
-Änderungen weiterhin angewendet. Ohne die
CircularLayout
, um sie zu binden, werden die zwölf Ziffern des Ziffernblatts vorgelesen
nachdem alle anderen Elemente auf dem Bildschirm besucht wurden. Dies geschieht
da für alle anderen Elemente der Standardwert für traversalIndex
0f
ist und der Wert
Ziffernblatt-Textelemente werden nach allen anderen 0f
-Elementen vorgelesen.
Beispiel: Durchlaufreihenfolge für unverankerte Aktionsschaltfläche anpassen
In diesem Beispiel steuern traversalIndex
und isTraversalGroup
den
Durchlaufreihenfolge einer unverankerten Aktionsschaltfläche (UAS) von Material Design. Grundlage
dieses Beispiels ist das folgende Layout:
Standardmäßig hat das Layout in diesem Beispiel die folgende TalkBack-Reihenfolge:
Obere App-Leiste → Beispieltexte 0 bis 6 → unverankerte Aktionsschaltfläche (UAS) → Unten App-Leiste
Möglicherweise soll sich der Screenreader zuerst auf die UAS konzentrieren. Um eine
traversalIndex
für ein Material-Element wie eine FAB:
@Composable fun FloatingBox() { Box(modifier = Modifier.semantics { isTraversalGroup = true; traversalIndex = -1f }) { FloatingActionButton(onClick = {}) { Icon(imageVector = Icons.Default.Add, contentDescription = "fab icon") } } }
In diesem Snippet wird ein Feld mit
isTraversalGroup
wurde auf true
gesetzt und ein traversalIndex
für dieselbe Box festgelegt
(-1f
ist niedriger als der Standardwert 0f
) bedeutet, dass das schwebende Feld
vor allen anderen Bildschirmelementen.
Als Nächstes können Sie die unverankerte Box und andere Elemente in ein Gerüst einfügen, ein Material-Design-Layout implementiert:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun ColumnWithFABFirstDemo() { Scaffold( topBar = { TopAppBar(title = { Text("Top App Bar") }) }, floatingActionButtonPosition = FabPosition.End, floatingActionButton = { FloatingBox() }, content = { padding -> ContentColumn(padding = padding) }, bottomBar = { BottomAppBar { Text("Bottom App Bar") } } ) }
TalkBack interagiert mit den Elementen in der folgenden Reihenfolge:
UAS → Obere App-Leiste → Beispieltexte 0 bis 6 → Untere App-Leiste
Weitere Informationen
- Barrierefreiheit:Grundlegende Konzepte und übliche Techniken für die Entwicklung von Android-Apps
- Barrierefreie Apps erstellen: Wichtige Schritte mit denen Sie die Barrierefreiheit Ihrer App
- Prinzipien zur Verbesserung von Apps Barrierefreiheit:Grundprinzipien für die Sie bei der Verbesserung der Barrierefreiheit Ihrer App
- Tests auf Barrierefreiheit: Testprinzipien und -tools für Bedienungshilfen unter Android