https://kotlinlang.org logo
#compose
Title
# compose
j

Jérémy CROS

03/26/2024, 10:09 AM
Hello everyone! 🙂 I’m currently facing an issue regarding LazyColumns and accessibility with Talkback. In my LazyColumn, I want to display two types of elements : some text headers and custom composables as list items. To do that, in my LazyColumn, I put every text header in an item{} block and iterate on my list items to display them in an items{} block. The issue is when I activate TalkBack to read the screen content, the focus order is not the one I expected. In fact, the elements inside the item{} blocks are focused first, and only after, the elements inside the items{} blocks are. More details in thread 🧵
I found this similar bug reported on Issue Tracker : https://issuetracker.google.com/issues/232293357?pli=1 , but it doesn’t seem to have been fixed yet. I have already tried some workarounds but it doesn’t work either : • I tried not to have both item{} and items{} block in my LazyColumn. To do that, I wrapped all my items in a sealed class in which I define whether an element should be of type header or list item. Then, in my LazyColumn I have a single items{} block in which I iterate over my elements, and using a « when » block, I decide which composable to display according to the current element’s type. • I have also tried not to use LazyColumn but a Column instead (as I already know how many elements will be displayed, and the size of the list should not exceed the screen size). Inside this Column, I simply put Text composables for headers and iterates over my list items using a « forEach » block. And surprisingly, I get the same behavior as described previously. In all these cases I tried playing with semantics Modifier, using traversalGroup and traversalIndexes but I didn’t find anything that fixes this issue.
Copy code
LazyColumn {
  if (itemsList.isNotEmpty()) {
    item {
      Text(…)
      Divider()
    }
    items(
      items = itemsList,
      itemContent = { item ->
        ListItemComposable(
          label = item.label,
          …
        )
        Divider()
      }
    )
  }
  item {
    Text(…)
    Divider()

    CustomListItem1(…)
    Divider()

    CustomListItem2(…)
    Divider()
  }
}
j

Josh Eldridge

03/26/2024, 5:01 PM
So in the snippet above, is Talkback reading the above and below
item{}
blocks first and then it focuses the iterated items?
j

Jérémy CROS

03/27/2024, 8:32 AM
Yes, unfortunately, that's the behavior we have 😕
j

Josh Eldridge

03/27/2024, 2:40 PM
Yikes 😬, well I added a +1 to that issue to help with visibility. I did similar work with TalkBack but I guess I never tried to have it do it on a foreach list of items with text headers. A lot of our sub items were static in a settings screen I believe
3 Views