Reputation: 3893
Let's say I have a Column with Rows. Each Row is a logical unit and I want Talkback to navigate through the Column Row by Row, without selecting and descendants of the row. That's easily achievable with mergeDescendants = true
Now, I have a tailored contentDescription for the Row, that provides a more natural description. How do I ignore the descendant's text to be read, to prevent doubling the information?
tl;dr: When using mergeDescendants
; how do I make Talkback replace rather than merge the descendants' contentDescriptions?
@Composable
fun Greeting() {
// Goal: Each row is a single entity for talkback, that has a content desccription describing the entire tow
// descendants should not be focused when navigating by swipe w/ talkback
// "Greeting for Android X" should be read, descendants should not be read automatically.
Column(modifier = Modifier.padding(20.dp)) {// Screen padding
Box(
// "greeting for Android 1 ... Hello Android! ... How do you do?" :-(
// descendants can not be selected individually :-)
Modifier.semantics(mergeDescendants = true) {
contentDescription = "greeting for Android 1"
}
) {
Row {
Text(text = "Hello Android!", modifier = Modifier.padding(32.dp))
Text(text = "How do you do?", modifier = Modifier.padding(32.dp))
}
}
Box(
// "greeting for Android 2" :-)
// descendants will be traversed next :-(
Modifier.semantics {
contentDescription = "greeting for Android 2"
}
) {
Row {
Text(text = "Hello Android!", modifier = Modifier.padding(32.dp))
Text(text = "How do you do?", modifier = Modifier.padding(32.dp))
}
}
Box(
// "greeting for Android 3" :-)
// descendants can not be selected individually :-)
// When using tap to speak rather than swipe, it is hard to select the row:
// Only when tapping empty space will the row be selected.
// When tapping either text element,nothing happens. :-(
// Expected: the row is selected and "greeting for android 3" is read when
// I tap anywhere inside it's bounds
Modifier.semantics {
contentDescription = "greeting for Android 3"
}
) {
Row(Modifier.clearAndSetSemantics {}) {
Text(text = "Hello Android!", modifier = Modifier.padding(32.dp))
Text(text = "How do you do?", modifier = Modifier.padding(32.dp))
}
}
}
}
Upvotes: 7
Views: 8436
Reputation: 2075
I assume that in the code you presented above the top level Box
represents your "rows". Try firstly merging semantic properties of Box's children and then clearing all of them and setting your custom content description by applying the following modifier to Box:
Modifier
.semantics(mergeDescendants = true) {}
.clearAndSetSemantics { contentDescription = "greeting for Android 1" }
Additionally, you could also explicitly call the following on each Box's children to ensure their semantic properties are ignored:
Modifier.clearAndSetSemantics {}
Upvotes: 7