diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java index db3dd2871cc6..52fefed75e40 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java @@ -21,7 +21,6 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.view.AccessibilityDelegateCompat; import androidx.core.view.ViewCompat; import com.facebook.common.logging.FLog; import com.facebook.react.R; @@ -174,11 +173,7 @@ public BaseViewManager(@Nullable ReactApplicationContext reactContext) { view.setFocusableInTouchMode(false); // Accessibility state the props apply to the view itself, as a new view has it. The delegate - // stays, since a view's constructor may have installed it, and forgets what it cached. - AccessibilityDelegateCompat accessibilityDelegate = ViewCompat.getAccessibilityDelegate(view); - if (accessibilityDelegate instanceof ReactAccessibilityDelegate) { - ((ReactAccessibilityDelegate) accessibilityDelegate).internal_prepareToRecycle(); - } + // stays, since a view's constructor may have installed it. view.setContentDescription(null); view.setSelected(false); view.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_AUTO); @@ -498,11 +493,7 @@ private void updateViewContentDescription(@NonNull T view) { } @ReactProp(name = ViewProps.ACCESSIBILITY_ACTIONS) - public void setAccessibilityActions(T view, ReadableArray accessibilityActions) { - if (accessibilityActions == null) { - return; - } - + public void setAccessibilityActions(T view, @Nullable ReadableArray accessibilityActions) { view.setTag(R.id.accessibility_actions, accessibilityActions); } diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt index 6c76b73ffca6..f1fe6dccf762 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactAccessibilityDelegate.kt @@ -57,7 +57,6 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac host?.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED) } } - private val accessibilityActionsMap = HashMap() init { // We need to reset these two properties, as ExploreByTouchHelper sets focusable to "true" and @@ -68,12 +67,6 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac hostView.importantForAccessibility = originalImportantForAccessibility } - /** Forgets the actions cached from the props of a view that is about to be recycled. */ - @JvmName("internal_prepareToRecycle") - internal fun prepareToRecycle() { - accessibilityActionsMap.clear() - } - override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) { super.onInitializeAccessibilityNodeInfo(host, info) @@ -135,7 +128,6 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac val actionId: Int = actionIdMap.get(actionName) ?: customActionIdMap.getOrPut(actionName) { customActionCounter++ } - accessibilityActionsMap[actionId] = actionName val accessibilityAction = AccessibilityActionCompat(actionId, actionLabel) info.addAction(accessibilityAction) } @@ -230,9 +222,10 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac if (action == AccessibilityNodeInfoCompat.ACTION_EXPAND) { host.setTag(R.id.accessibility_state_expanded, true) } - if (accessibilityActionsMap.containsKey(action)) { + val actionName = findDeclaredActionName(host, action) + if (actionName != null) { val eventData = createMap() - eventData.putString("actionName", accessibilityActionsMap[action]) + eventData.putString("actionName", actionName) if ( action == AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_PROGRESS.id && args?.containsKey(AccessibilityNodeInfo.ACTION_ARGUMENT_PROGRESS_VALUE) == true @@ -278,6 +271,22 @@ public open class ReactAccessibilityDelegate( // The View this delegate is attac return super.performAccessibilityAction(host, action, args) } + private fun findDeclaredActionName(host: View, actionId: Int): String? { + val accessibilityActions = + host.getTag(R.id.accessibility_actions) as ReadableArray? ?: return null + for (i in 0.. Unit = {}, @@ -447,4 +497,18 @@ class BaseViewManagerTest { null, JSResponderHandler(), ) + + private fun applyAccessibilityActions(accessibilityActions: JavaOnlyArray?) { + viewManager.updateProperties( + view, + ReactStylesDiffMap(JavaOnlyMap.of(ViewProps.ACCESSIBILITY_ACTIONS, accessibilityActions)), + ) + } + + private fun performAccessibilityClick(): Int { + var clicks = 0 + view.setOnClickListener { clicks++ } + view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, null) + return clicks + } }