You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 6f73542
Browse filesBrowse the repository at this point in the historyBrowse files
Reset accessibility state when recycling Android views (#59047)
Summary:
With `enableViewRecycling` on, a recycled view keeps the accessibility state its previous props applied. `BaseViewManager.prepareToRecycleView` clears the accessibility tags, but not the content description, `importantForAccessibility`, the selected state, the live region, `screenReaderFocusable`, the `role` and collection tags, or the actions its accessibility delegate cached. The next view of that type is built from it and applies only the props it declares, so TalkBack announces a label and a role the view never had, the delegate sends TalkBack's click to an action only the previous props declared, and a view last used inside an `aria-hidden` subtree hides its new content from accessibility services. With `experimental_accessibilityOrder` on as well, a recycled `ReactViewGroup` keeps its previous order list, and a recycled child keeps the parent and focusability tags its former parent's order put on it.
This resets that state in `prepareToRecycleView` to what a new view has, clears the order list in `ReactViewGroup.initView`, and restores `TextView`'s default importance in `ReactTextView.recycleView`. The delegate stays, since `ReactScrollView`, `ReactHorizontalScrollView` and `ReactNestedScrollView` install theirs in their constructors: a new `ReactAccessibilityDelegate.prepareToRecycle()` clears the actions it cached, and `accessibilityLabelledBy`, read only in the call that sets it, is a local there. It sits beside the `enabled` reset #58799 added.
## Changelog:
[ANDROID] [FIXED] - Recycled views no longer keep the accessibility state of their previous props
Pull Request resolved: #59047
Test Plan:
New cases in `BaseViewManagerTest` and `ReactTextViewPropertyTest` recycle a view through `onDropViewInstance` and `createView` and compare it with a new one. Before the change six fail: content description `"Dismiss sheet"`, `role` tag `LIST`, a click dispatched to the previous props' `activate` action instead of performed, importance `4` where a new text view has `1`, the order list `["first"]`, and the former parent in `accessibility_order_parent`. Another case recycles each scroll view and checks that it keeps the `ReactScrollViewAccessibilityDelegate` its constructor installed. With the change, `./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest -PenableWarningsAsErrors=true` passes (727 tests) and the release sources compile with the same flag; the RNTester debug build and the rest of `build_android` were not run.
RNTester with view recycling on, on an Android 16 emulator with TalkBack, [before and after](#59047 (comment)): plain rows mounted after labelled rows were removed are read as a selected "Dismiss sheet" button without the change, and as their text with it.
On a Galaxy S23 (Android 14) app with view recycling on, plain rows mounted after rows carrying `aria-label`, `role`, `aria-selected`, `aria-disabled` and `aria-hidden` were removed reported the removed rows' label as their content description before the change. Built from source with it, the same rows report no label, role, selected or disabled state, and their text is in the accessibility tree.
Both device runs used the first revision of this change, which cleared the delegate on recycle instead of resetting it.
Reviewed By: Abbondanzo
Differential Revision: D125427268
Pulled By: javache
fbshipit-source-id: 1dad635ef6f1e5cef351d355865edc567f7bce58
Copy file name to clipboardExpand all lines: packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt
+9-4Lines changed: 9 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -58,7 +58,6 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac
Copy file name to clipboardExpand all lines: packages/react-native/ReactAndroid/src/test/java/com/facebook/react/views/text/ReactTextViewPropertyTest.kt
0 commit comments