The simplest version of the problem looks like this:
Column(modifier = Modifier.clickable { }.padding(all = 16.dp)) {
AndroidView(factory = ::TextView, update = { it.text = "AndroidView" })
Text("Composable")
}
Here we have a clickable container that contains two elements:
AndroidView
that contains a TextViewText
composableWhen I focus the container, I would expect TalkBack to announce both text elements, but it only announces the second. Here are some things that I've tried:
clickable
from the container. Without clickable
, TalkBack is happy to announce the AndroidView
. So it doesn’t seem like AndroidView
is inherently incompatible with TalkBack.semantics(mergeDescendents = true) {}
to the container. This makes no difference.semantics { contentDescription = "AndroidView" }
to the AndroidView
. This makes no difference.semantics { text = "AndroidView" }
to the AndroidView
. The text appears when I print the semantic tree, but still isn't announced by TalkBack.Why isn’t TalkBack picking up the AndroidView
?
Seems like it's a known issue. mergeDescendants
is set to true
when Modifier.clickable
is applied and it works only with Compose semantics nodes, not taking native Views into consideration. Check these issues:
https://issuetracker.google.com/issues/404479701
https://issuetracker.google.com/issues/349853793
As a workaround, you can wrap your AndroidView within a Box and set custom semantics:
Column(
modifier = Modifier
.clickable { }
.padding(all = 8.dp)
) {
Box(
modifier = Modifier.semnatics {
contentDescription = "AndroidView"
}
) {
AndroidView(
factory = {
TextView(it).also { textView ->
textView.text = "AndroidView"
}
})
}
Text("Composable")
}