VirtualView v2 support in HorizontalScrollView native component (Android) (#53890)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53890

Changelog: [Internal] -  Adds support for VirtualView v2 in Android HorizontalScrollView native component by implementing VirtualViewContainer interface. Only on Android because iOS equivalent native components are already set up to support virtualview v2 on horizontal scrollviews.

## Changes in Detail

Adds necessary changes to Android `HorizontalScrollView` native component to support the experimental version of VirtualView.

Reviewed By: lunaleaps

Differential Revision: D82783403

fbshipit-source-id: 1e55eb054ab098af5ca8dd526b27c574025943c4
This commit is contained in:
Calix Tang
2025-09-23 16:06:40 -07:00
committed by Facebook GitHub Bot
parent 14dc03e2bd
commit 53f89bacd4
2 changed files with 28 additions and 2 deletions
@@ -5566,7 +5566,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/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 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, com/facebook/react/views/scroll/VirtualViewContainer {
public fun <init> (Landroid/content/Context;)V
public fun <init> (Landroid/content/Context;Lcom/facebook/react/views/scroll/FpsListener;)V
public fun abortAnimation ()V
@@ -5596,6 +5596,7 @@ public class com/facebook/react/views/scroll/ReactHorizontalScrollView : android
public fun getScrollEnabled ()Z
public fun getScrollEventThrottle ()I
public fun getStateWrapper ()Lcom/facebook/react/uimanager/StateWrapper;
public fun getVirtualViewContainerState ()Lcom/facebook/react/views/scroll/VirtualViewContainerState;
protected fun handleInterceptedTouchEvent (Landroid/view/MotionEvent;)V
public fun isPartiallyScrolledInView (Landroid/view/View;)Z
protected fun onAttachedToWindow ()V
@@ -79,7 +79,8 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
HasStateWrapper,
HasFlingAnimator,
HasScrollEventThrottle,
HasSmoothScroll {
HasSmoothScroll,
VirtualViewContainer {
private static boolean DEBUG_MODE = false && ReactBuildConfig.DEBUG;
private static String TAG = ReactHorizontalScrollView.class.getSimpleName();
@@ -100,6 +101,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private final ValueAnimator DEFAULT_FLING_ANIMATOR = ObjectAnimator.ofInt(this, "scrollX", 0, 0);
private Rect mOverflowInset = new Rect();
private @Nullable VirtualViewContainerState mVirtualViewContainerState;
private boolean mActivelyScrolling;
private @Nullable Rect mClippingRect;
private Overflow mOverflow = Overflow.SCROLL;
@@ -156,6 +158,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
*/
private void initView() {
mOverflowInset = new Rect();
mVirtualViewContainerState = null;
mActivelyScrolling = false;
mClippingRect = null;
// The default value for `overflow` is set to `Visible` in the Yoga style props.
@@ -209,6 +212,15 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private void updateView() {}
@Override
public VirtualViewContainerState getVirtualViewContainerState() {
if (mVirtualViewContainerState == null) {
mVirtualViewContainerState = new VirtualViewContainerState(this);
}
return mVirtualViewContainerState;
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
@@ -512,6 +524,9 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
}
ReactScrollViewHelper.emitLayoutEvent(this);
if (mVirtualViewContainerState != null) {
mVirtualViewContainerState.updateState();
}
}
/**
@@ -605,7 +620,11 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
this,
mOnScrollDispatchHelper.getXFlingVelocity(),
mOnScrollDispatchHelper.getYFlingVelocity());
if (mVirtualViewContainerState != null) {
mVirtualViewContainerState.updateState();
}
}
} finally {
Systrace.endSection(Systrace.TRACE_TAG_REACT);
}
@@ -856,6 +875,9 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
if (mRemoveClippedSubviews) {
updateClippingRect();
}
if (mVirtualViewContainerState != null) {
mVirtualViewContainerState.updateState();
}
}
@Override
@@ -875,6 +897,9 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
if (mMaintainVisibleContentPositionHelper != null) {
mMaintainVisibleContentPositionHelper.stop();
}
if (mVirtualViewContainerState != null) {
mVirtualViewContainerState.cleanup();
}
}
@Override