Search code examples
androidandroid-recyclerviewaccessibilityandroid-a11y

RecyclerView accessibility traversal for lazy-loaded children in RecyclerView


We can populate a RecyclerView with items and, on binding, we can mark some of those items as 'headings' for accessibility.

This means that in the 'headings' traversal mode of TalkBack, the user can navigate directly between them.

However, a RecyclerView obviously binds and unbinds children as it scrolls. At any one time, there may only be a small subset of the total heading items loaded into view holders. Traversal between only those items is unhelpful and confusing.

Is there a way, or even best practice, to provision the RecyclerView such that we simultaneously satisfy (a) performant view recycling and (b) meaningful traversal for accessibility across the entire set of content?


Solution

  • Not all of the items considered headings in your source data set will be visibly present in the RecyclerView at any one time, just those in the current subset of the data presented by the RecycleView.Adapter. Without being visible on screen, accessibility services like TalkBack don't have access to those other headings and therefore will not interact with them.

    Technically, you could look at setting up custom handling of the accessibility tree, but this would need to handle all accessibility info for the view, not just the headings, and would likely impact performance especially for large data sets. There is no way to override the heading handling alone.

    The behaviour your describe is default and expected behaviour on Android, even if it doesn't seem ideal from a screen reader user experience perspective.