From 8a12672e8a984a3664e60051fed93834fd1eb833 Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Thu, 16 Jan 2025 10:05:30 -0800 Subject: [PATCH] Declare shared interface for accessibility delegate methods (#48543) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/48543 Introduces a shared interface for methods that need to be called by the `ReactScrollViewAccessibilityDelegate` Changelog: [Internal] Reviewed By: alanleedev Differential Revision: D67948151 fbshipit-source-id: 9bafaa0b5f9ad5ba2fd73b7b1929d784fa4951c9 --- .../ReactAndroid/api/ReactAndroid.api | 5 +++-- .../views/scroll/ReactAccessibleScrollView.kt | 19 +++++++++++++++++++ .../scroll/ReactHorizontalScrollView.java | 2 ++ .../react/views/scroll/ReactScrollView.java | 4 +++- .../ReactScrollViewAccessibilityDelegate.kt | 16 ++++++---------- 5 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactAccessibleScrollView.kt diff --git a/packages/react-native/ReactAndroid/api/ReactAndroid.api b/packages/react-native/ReactAndroid/api/ReactAndroid.api index 9a414995c9c..b6ccba4cf9e 100644 --- a/packages/react-native/ReactAndroid/api/ReactAndroid.api +++ b/packages/react-native/ReactAndroid/api/ReactAndroid.api @@ -6673,7 +6673,7 @@ public final class com/facebook/react/views/scroll/ReactHorizontalScrollContaine public final class com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager$Companion { } -public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android/widget/HorizontalScrollView, android/view/View$OnLayoutChangeListener, android/view/ViewGroup$OnHierarchyChangeListener, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollEventThrottle, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState, com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll, com/facebook/react/views/scroll/ReactScrollViewHelper$HasStateWrapper { +public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android/widget/HorizontalScrollView, android/view/View$OnLayoutChangeListener, android/view/ViewGroup$OnHierarchyChangeListener, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/views/scroll/ReactAccessibleScrollView, com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollEventThrottle, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState, com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll, com/facebook/react/views/scroll/ReactScrollViewHelper$HasStateWrapper { public fun (Landroid/content/Context;)V public fun (Landroid/content/Context;Lcom/facebook/react/views/scroll/FpsListener;)V public fun abortAnimation ()V @@ -6798,7 +6798,7 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollViewManager : public fun updateState (Lcom/facebook/react/views/scroll/ReactHorizontalScrollView;Lcom/facebook/react/uimanager/ReactStylesDiffMap;Lcom/facebook/react/uimanager/StateWrapper;)Ljava/lang/Object; } -public class com/facebook/react/views/scroll/ReactScrollView : android/widget/ScrollView, android/view/View$OnLayoutChangeListener, android/view/ViewGroup$OnHierarchyChangeListener, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollEventThrottle, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState, com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll, com/facebook/react/views/scroll/ReactScrollViewHelper$HasStateWrapper { +public class com/facebook/react/views/scroll/ReactScrollView : android/widget/ScrollView, android/view/View$OnLayoutChangeListener, android/view/ViewGroup$OnHierarchyChangeListener, com/facebook/react/uimanager/ReactClippingViewGroup, com/facebook/react/uimanager/ReactOverflowViewWithInset, com/facebook/react/views/scroll/ReactAccessibleScrollView, com/facebook/react/views/scroll/ReactScrollViewHelper$HasFlingAnimator, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollEventThrottle, com/facebook/react/views/scroll/ReactScrollViewHelper$HasScrollState, com/facebook/react/views/scroll/ReactScrollViewHelper$HasSmoothScroll, com/facebook/react/views/scroll/ReactScrollViewHelper$HasStateWrapper { public fun (Landroid/content/Context;)V public fun (Landroid/content/Context;Lcom/facebook/react/views/scroll/FpsListener;)V public fun abortAnimation ()V @@ -6821,6 +6821,7 @@ public class com/facebook/react/views/scroll/ReactScrollView : android/widget/Sc public fun getScrollEventThrottle ()I public fun getStateWrapper ()Lcom/facebook/react/uimanager/StateWrapper; protected fun handleInterceptedTouchEvent (Landroid/view/MotionEvent;)V + public fun isPartiallyScrolledInView (Landroid/view/View;)Z protected fun onAttachedToWindow ()V public fun onChildViewAdded (Landroid/view/View;Landroid/view/View;)V public fun onChildViewRemoved (Landroid/view/View;Landroid/view/View;)V diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactAccessibleScrollView.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactAccessibleScrollView.kt new file mode 100644 index 00000000000..9849e242311 --- /dev/null +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactAccessibleScrollView.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.views.scroll + +import android.view.View + +/** Shared interface for the [ReactScrollViewAccessibilityDelegate] */ +internal interface ReactAccessibleScrollView { + + val scrollEnabled: Boolean + + /** Returns whether the given descendent is partially scrolled in view */ + fun isPartiallyScrolledInView(view: View): Boolean +} diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 5692c86c1c2..e037f05ad19 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -71,6 +71,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements ReactClippingViewGroup, ViewGroup.OnHierarchyChangeListener, View.OnLayoutChangeListener, + ReactAccessibleScrollView, ReactOverflowViewWithInset, HasScrollState, HasStateWrapper, @@ -456,6 +457,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView } /** Returns whether the given descendent is partially scrolled in view */ + @Override public boolean isPartiallyScrolledInView(View descendent) { int scrollDelta = getScrollDelta(descendent); descendent.getDrawingRect(mTempRect); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index adf92c118ea..71acfa6288b 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -76,6 +76,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGroup, ViewGroup.OnHierarchyChangeListener, View.OnLayoutChangeListener, + ReactAccessibleScrollView, ReactOverflowViewWithInset, HasScrollState, HasStateWrapper, @@ -380,7 +381,8 @@ public class ReactScrollView extends ScrollView } /** Returns whether the given descendent is partially scrolled in view */ - boolean isPartiallyScrolledInView(View descendent) { + @Override + public boolean isPartiallyScrolledInView(View descendent) { int scrollDelta = getScrollDelta(descendent); descendent.getDrawingRect(mTempRect); return scrollDelta != 0 && Math.abs(scrollDelta) < mTempRect.width(); diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewAccessibilityDelegate.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewAccessibilityDelegate.kt index 5a59f5b5eeb..1dc032aa1f7 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewAccessibilityDelegate.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewAccessibilityDelegate.kt @@ -25,25 +25,25 @@ internal class ReactScrollViewAccessibilityDelegate : AccessibilityDelegateCompa override fun onInitializeAccessibilityEvent(host: View, event: AccessibilityEvent) { super.onInitializeAccessibilityEvent(host, event) - if (host is ReactScrollView || host is ReactHorizontalScrollView) { + if (host is ReactAccessibleScrollView) { onInitializeAccessibilityEventInternal(host, event) } else { ReactSoftExceptionLogger.logSoftException( TAG, AssertionException( - "ReactScrollViewAccessibilityDelegate should only be used with ReactScrollView or ReactHorizontalScrollView, not with class: ${host.javaClass.simpleName}")) + "ReactScrollViewAccessibilityDelegate should only be used with ReactAccessibleScrollView, not with class: ${host.javaClass.simpleName}")) } } override fun onInitializeAccessibilityNodeInfo(host: View, info: AccessibilityNodeInfoCompat) { super.onInitializeAccessibilityNodeInfo(host, info) - if (host is ReactScrollView || host is ReactHorizontalScrollView) { + if (host is ReactAccessibleScrollView) { onInitializeAccessibilityNodeInfoInternal(host, info) } else { ReactSoftExceptionLogger.logSoftException( TAG, AssertionException( - "ReactScrollViewAccessibilityDelegate should only be used with ReactScrollView or ReactHorizontalScrollView, not with class: ${host.javaClass.simpleName}")) + "ReactScrollViewAccessibilityDelegate should only be used with ReactAccessibleScrollView, not with class: ${host.javaClass.simpleName}")) } } @@ -61,9 +61,7 @@ internal class ReactScrollViewAccessibilityDelegate : AccessibilityDelegateCompa for (index in 0..