react-native
react-native copied to clipboard
Android: Expandable/Collapsible State
Description
The "expanded" accessibilityState for Android is currently faked by appending to the content description, rather than implemented correctly. This has all sorts of side effects, such as:
- On some components, the state expanded/collapsed is properly announced on focus, on some it is not.
- On some components only the expanded/collapsed state is announced, and not other component text.
- Upon change, state change is not always announced.
- The accessibilityState's "expanded" field does not seem to work on all element types (for example, it has no effect on <Button>'s).
- using accessibilityActions it is possible to add an action for expand/collapse, but these are treated as custom actions and must have their own label defined, rather than using Androids built in expand/collapse actions, which Talkback has predefined labels for.
React Native version:
v0.63
Expected Behavior
Upon focus, either "expanded" or "collapsed" should be announced, depending on whether the accessibilityState's "expanded" field is set to true or false. Upon state change, the new state should be announced. If an expand/collapse action is desired, you should be able to use the default system ones, rather than having to define custom ones yourself.
Snack
https://snack.expo.io/0YOQfXFBi
Android Details
Expandable and Collapsible are unique in the Android Accessibility API, in that they are not represented as properties on the View
or AccessibilityNodeInfo
, but are only represented as AccessibilityActions
on the AccessibilityNodeInfo. This means that Talkback determines whether or not a node is "expandable" or "collapsible", or potentially even both, by looking at the list of AccessibilityActions attached to the AccessibilityNodeInfo.
When setting the accessibilityState's expandable property, it should correlate to adding an action of either AccessibilityNodeInfoCompat.ACTION_EXPAND
or AccessibilityNodeInfoCompat.ACTION_COLLAPSE
on the AccessibilityNodeInfo. This work should be done in the ReactAccessibilityDelegate
class's
Currently, this feature is being "faked" by appending to the contentDescription in the BaseViewManager class. This should be removed when this feature is implemented properly.
I'll try it.
@amarlette @blavalla @kacieb @grgr-dkrk
Hello all, I would like to take this one on... if @grgr-dkrk is no longer working on it, if i am able to take it on, could someone, asign it to me?
I'm preparing a solution for this issue. I tested the solution proposed by the author of the Issues, and it seems to work.
Related to the issue Main Branch - onAccessibilityAction not called on Fabric renderer detected on the main branch and not related to this issue.
https://github.com/facebook/react-native/blob/163171ccab6937785f4f3c85e011bd14540bebf5/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java#L121-L123
E/unknown:ReactEventEmitter( 3845): com.facebook.react.bridge.ReactNoCrashSoftException:
Cannot find EventEmitter for receiveEvent: SurfaceId[1] ReactTag[104] UIManagerType[2] EventName[topAccessibilityAction]
E/unknown:ReactEventEmitter( 3845):
at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
E/unknown:ReactEventEmitter( 3845):
at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
full log
E/unknown:ReactEventEmitter( 6121): at com.facebook.react.uimanager.events.ReactEventEmitter.receiveEvent(ReactEventEmitter.java:151)
E/unknown:ReactEventEmitter( 6121): at com.facebook.react.uimanager.events.Event.dispatchModern(Event.java:229)
E/unknown:ReactEventEmitter( 6121): at com.facebook.react.uimanager.events.EventDispatcherImpl$DispatchEventsRunnable.run(EventDispatcherImpl.java:370)
E/unknown:ReactEventEmitter( 6121): at android.os.Handler.handleCallback(Handler.java:938)
E/unknown:ReactEventEmitter( 6121): at android.os.Handler.dispatchMessage(Handler.java:99)
E/unknown:ReactEventEmitter( 6121): at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
E/unknown:ReactEventEmitter( 6121): at android.os.Looper.loopOnce(Looper.java:201)
E/unknown:ReactEventEmitter( 6121): at android.os.Looper.loop(Looper.java:288)
E/unknown:ReactEventEmitter( 6121): at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
E/unknown:ReactEventEmitter( 6121): at java.lang.Thread.run(Thread.java:1012)
https://github.com/facebook/react-native/blob/163171ccab6937785f4f3c85e011bd14540bebf5/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/ReactEventEmitter.java#L130-L140