Skip to content

Commit 52a4f4b

Browse files
fabriziocuccimeta-codesync[bot]
authored andcommitted
Reset onClickListener in prepareToRecycleView (#54619)
Summary: Pull Request resolved: #54619 Changelog: [Android][Fixed] - Reset OnClickListener when recycling views to prevent accessibility tools from detecting incorrect state Reviewed By: javache Differential Revision: D87545806 fbshipit-source-id: 295bae9476ca99ee96f140233392ce9a8c12e649
1 parent 45c59f0 commit 52a4f4b

21 files changed

+159
-40
lines changed

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlags.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<783b32e7fdda85b8577753f0553288d5>>
7+
* @generated SignedSource<<87d3308992d9f10b714b3b8c53da6b1b>>
88
*/
99

1010
/**
@@ -450,6 +450,12 @@ public object ReactNativeFeatureFlags {
450450
@JvmStatic
451451
public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = accessor.shouldPressibilityUseW3CPointerEventsForHover()
452452

453+
/**
454+
* Reset OnClickListener to null when recycling views on Android to avoid accessibility tools finding views with incorrect state after recycling.
455+
*/
456+
@JvmStatic
457+
public fun shouldResetOnClickListenerWhenRecyclingView(): Boolean = accessor.shouldResetOnClickListenerWhenRecyclingView()
458+
453459
/**
454460
* Fix BaseViewManager to properly set view.setEnabled() based on accessibilityState.disabled.
455461
*/

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxAccessor.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<15bb2229e65b6a6ae728d512ff51885f>>
7+
* @generated SignedSource<<b5efd0c0e73a02a3016733d6d49b981d>>
88
*/
99

1010
/**
@@ -90,6 +90,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
9090
private var preparedTextCacheSizeCache: Double? = null
9191
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
9292
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
93+
private var shouldResetOnClickListenerWhenRecyclingViewCache: Boolean? = null
9394
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
9495
private var shouldSetIsClickableByDefaultCache: Boolean? = null
9596
private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null
@@ -741,6 +742,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
741742
return cached
742743
}
743744

745+
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean {
746+
var cached = shouldResetOnClickListenerWhenRecyclingViewCache
747+
if (cached == null) {
748+
cached = ReactNativeFeatureFlagsCxxInterop.shouldResetOnClickListenerWhenRecyclingView()
749+
shouldResetOnClickListenerWhenRecyclingViewCache = cached
750+
}
751+
return cached
752+
}
753+
744754
override fun shouldSetEnabledBasedOnAccessibilityState(): Boolean {
745755
var cached = shouldSetEnabledBasedOnAccessibilityStateCache
746756
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<85a6247f6049f60c18efdce5db0cccdf>>
7+
* @generated SignedSource<<e4603ced557b3baeb7a88f270678a437>>
88
*/
99

1010
/**
@@ -168,6 +168,8 @@ public object ReactNativeFeatureFlagsCxxInterop {
168168

169169
@DoNotStrip @JvmStatic public external fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
170170

171+
@DoNotStrip @JvmStatic public external fun shouldResetOnClickListenerWhenRecyclingView(): Boolean
172+
171173
@DoNotStrip @JvmStatic public external fun shouldSetEnabledBasedOnAccessibilityState(): Boolean
172174

173175
@DoNotStrip @JvmStatic public external fun shouldSetIsClickableByDefault(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsDefaults.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<614d228af81090b8b1dee65f4bfb67d7>>
7+
* @generated SignedSource<<50435a85758921672f7c05c6ac6790f9>>
88
*/
99

1010
/**
@@ -163,6 +163,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi
163163

164164
override fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean = false
165165

166+
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean = false
167+
166168
override fun shouldSetEnabledBasedOnAccessibilityState(): Boolean = true
167169

168170
override fun shouldSetIsClickableByDefault(): Boolean = false

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsLocalAccessor.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<e4971d843cf79d94f8c61394f4c27204>>
7+
* @generated SignedSource<<aedd122d17339b8c2acf189c1bb00f4d>>
88
*/
99

1010
/**
@@ -94,6 +94,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
9494
private var preparedTextCacheSizeCache: Double? = null
9595
private var preventShadowTreeCommitExhaustionCache: Boolean? = null
9696
private var shouldPressibilityUseW3CPointerEventsForHoverCache: Boolean? = null
97+
private var shouldResetOnClickListenerWhenRecyclingViewCache: Boolean? = null
9798
private var shouldSetEnabledBasedOnAccessibilityStateCache: Boolean? = null
9899
private var shouldSetIsClickableByDefaultCache: Boolean? = null
99100
private var shouldTriggerResponderTransferOnScrollAndroidCache: Boolean? = null
@@ -815,6 +816,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
815816
return cached
816817
}
817818

819+
override fun shouldResetOnClickListenerWhenRecyclingView(): Boolean {
820+
var cached = shouldResetOnClickListenerWhenRecyclingViewCache
821+
if (cached == null) {
822+
cached = currentProvider.shouldResetOnClickListenerWhenRecyclingView()
823+
accessedFeatureFlags.add("shouldResetOnClickListenerWhenRecyclingView")
824+
shouldResetOnClickListenerWhenRecyclingViewCache = cached
825+
}
826+
return cached
827+
}
828+
818829
override fun shouldSetEnabledBasedOnAccessibilityState(): Boolean {
819830
var cached = shouldSetEnabledBasedOnAccessibilityStateCache
820831
if (cached == null) {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/internal/featureflags/ReactNativeFeatureFlagsProvider.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<e7b49105c0cea6be905be90610f0c7e4>>
7+
* @generated SignedSource<<f09b47e1200d3164ee5f495ef991d6cf>>
88
*/
99

1010
/**
@@ -163,6 +163,8 @@ public interface ReactNativeFeatureFlagsProvider {
163163

164164
@DoNotStrip public fun shouldPressibilityUseW3CPointerEventsForHover(): Boolean
165165

166+
@DoNotStrip public fun shouldResetOnClickListenerWhenRecyclingView(): Boolean
167+
166168
@DoNotStrip public fun shouldSetEnabledBasedOnAccessibilityState(): Boolean
167169

168170
@DoNotStrip public fun shouldSetIsClickableByDefault(): Boolean

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/BaseViewManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ public BaseViewManager(@Nullable ReactApplicationContext reactContext) {
152152
if (ReactNativeFeatureFlags.shouldSetIsClickableByDefault()) {
153153
view.setClickable(true);
154154
}
155+
if (ReactNativeFeatureFlags.shouldResetOnClickListenerWhenRecyclingView()) {
156+
view.setOnClickListener(null);
157+
}
155158
view.setFocusable(false);
156159
view.setFocusableInTouchMode(false);
157160

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<2f04d4a48caf61c182d412b2ae335e3a>>
7+
* @generated SignedSource<<d30f5ffcbec1c5175623573fdbd0be87>>
88
*/
99

1010
/**
@@ -459,6 +459,12 @@ class ReactNativeFeatureFlagsJavaProvider
459459
return method(javaProvider_);
460460
}
461461

462+
bool shouldResetOnClickListenerWhenRecyclingView() override {
463+
static const auto method =
464+
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("shouldResetOnClickListenerWhenRecyclingView");
465+
return method(javaProvider_);
466+
}
467+
462468
bool shouldSetEnabledBasedOnAccessibilityState() override {
463469
static const auto method =
464470
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("shouldSetEnabledBasedOnAccessibilityState");
@@ -933,6 +939,11 @@ bool JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsFo
933939
return ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover();
934940
}
935941

942+
bool JReactNativeFeatureFlagsCxxInterop::shouldResetOnClickListenerWhenRecyclingView(
943+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
944+
return ReactNativeFeatureFlags::shouldResetOnClickListenerWhenRecyclingView();
945+
}
946+
936947
bool JReactNativeFeatureFlagsCxxInterop::shouldSetEnabledBasedOnAccessibilityState(
937948
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
938949
return ReactNativeFeatureFlags::shouldSetEnabledBasedOnAccessibilityState();
@@ -1274,6 +1285,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
12741285
makeNativeMethod(
12751286
"shouldPressibilityUseW3CPointerEventsForHover",
12761287
JReactNativeFeatureFlagsCxxInterop::shouldPressibilityUseW3CPointerEventsForHover),
1288+
makeNativeMethod(
1289+
"shouldResetOnClickListenerWhenRecyclingView",
1290+
JReactNativeFeatureFlagsCxxInterop::shouldResetOnClickListenerWhenRecyclingView),
12771291
makeNativeMethod(
12781292
"shouldSetEnabledBasedOnAccessibilityState",
12791293
JReactNativeFeatureFlagsCxxInterop::shouldSetEnabledBasedOnAccessibilityState),

packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<7bfc976ab923620e57f62282272dedb9>>
7+
* @generated SignedSource<<4fac1a3773ded6bb80528aab5662ca96>>
88
*/
99

1010
/**
@@ -240,6 +240,9 @@ class JReactNativeFeatureFlagsCxxInterop
240240
static bool shouldPressibilityUseW3CPointerEventsForHover(
241241
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
242242

243+
static bool shouldResetOnClickListenerWhenRecyclingView(
244+
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
245+
243246
static bool shouldSetEnabledBasedOnAccessibilityState(
244247
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
245248

packages/react-native/ReactCommon/react/featureflags/ReactNativeFeatureFlags.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @generated SignedSource<<6f9513178d03ce6e69dfc1b0182af336>>
7+
* @generated SignedSource<<d3573c8b6251753cc68d82cff6c4855e>>
88
*/
99

1010
/**
@@ -306,6 +306,10 @@ bool ReactNativeFeatureFlags::shouldPressibilityUseW3CPointerEventsForHover() {
306306
return getAccessor().shouldPressibilityUseW3CPointerEventsForHover();
307307
}
308308

309+
bool ReactNativeFeatureFlags::shouldResetOnClickListenerWhenRecyclingView() {
310+
return getAccessor().shouldResetOnClickListenerWhenRecyclingView();
311+
}
312+
309313
bool ReactNativeFeatureFlags::shouldSetEnabledBasedOnAccessibilityState() {
310314
return getAccessor().shouldSetEnabledBasedOnAccessibilityState();
311315
}

0 commit comments

Comments
 (0)