Skip to content

Android: TalkBack navigates inverted lists in reverse order #2381

Description

@sharabai

Description

On Android, TalkBack navigates a vertical FlashList with inverted={true} in the opposite direction from the visual and chronological order of its items.

This affects chat-like lists: the standard TalkBack gesture for moving to the next element focuses the previous message, while the gesture for moving to the previous element focuses the next message. The same list has the expected accessibility traversal order on iOS.

Current behavior

With TalkBack enabled on Android:

  • Swiping right to move to the next accessibility element focuses the previous message.
  • Swiping left to move to the previous accessibility element focuses the next message.
  • Users must reverse the normal TalkBack gestures to read the conversation in visual order.

Recording:

bug.mp4

Expected behavior

TalkBack traversal should follow the list's visual order:

  • The next gesture should focus the next visible message.
  • The previous gesture should focus the previous visible message.

Setting inverted={true} should reverse the list visually without reversing the semantic accessibility traversal exposed to TalkBack.

Reproduction

Expo Snack or minimal reproduction link:

https://snack.expo.dev/@sharabai/flashlist-reverted-list-accessibility-issue?platform=android

TalkBack cannot be tested in Snack's embedded preview. Run the Snack through Expo Go on an Android emulator or a physical Android device:

  1. Enable TalkBack on the Android emulator or physical device.
  2. Open the Snack in Expo Go.
  3. Focus a message in the inverted list.
  4. Swipe right to move to the next accessibility element.
  5. Observe that TalkBack focuses the previous visible message instead of the next one.
  6. Swipe left to move to the previous accessibility element.
  7. Observe that TalkBack focuses the next visible message instead of the previous one.

TalkBack navigates the inverted list in the direction opposite to its visual order.

Platform

  • iOS
  • Android
  • Web (if applicable)

Environment

React Native info output:
The original recording was captured in Expensify/App. Full `npx react-native info`
output was not captured with the report.

FlashList version: 2.3.0

Additional context

  • The issue is reproducible in Expensify staging and production.
  • iOS does not exhibit the reversed screen-reader traversal.
  • Sorting the rendered items so that their React/Fiber order matches their visual order did not fix Android TalkBack traversal. React Native DevTools confirmed that the elements were sorted correctly, but TalkBack still moved through them in the wrong direction. This suggests the issue is not caused solely by recycled items being out of order in the React tree.
  • FlashList implements Android inversion with a rotate(180deg) transform on the list and counter-transforms on its items. The Android accessibility traversal generated for this transformed hierarchy appears not to match the resulting visual order.
  • This fails WCAG 2.2 SC 1.3.2 (Meaningful Sequence) and SC 2.4.3 (Focus Order), because chronological message order is meaningful and sequential focus does not preserve it.
  • The current workaround is to use the opposite TalkBack gestures, which is confusing and contrary to normal screen-reader navigation.
  • Original downstream report: [$250] FlashList accessibility confusing order Android Expensify/App#94165

Checklist

  • I've searched existing issues and couldn't find a duplicate
  • I've provided a minimal reproduction (Expo Snack preferred)
  • I'm using the latest version of @shopify/flash-list
  • I've included all required information above

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions