diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewManager.kt b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewManager.kt index da19e945b52a9b..2f2453e97a1d0d 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewManager.kt +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactClippingViewManager.kt @@ -62,9 +62,6 @@ public abstract class ReactClippingViewManager : ViewGroupMa if (removeClippedSubviews) { val child = getChildAt(parent, index) if (child != null) { - if (child.parent != null) { - parent.removeView(child) - } parent.removeViewWithSubviewClippingEnabled(child) } } else { diff --git a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index b0cf176bc6136d..2b462cfd1956a8 100644 --- a/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -137,6 +137,7 @@ public void shutdown() { private @Nullable ViewGroupDrawingOrderHelper mDrawingOrderHelper; private float mBackfaceOpacity; private String mBackfaceVisibility; + private @Nullable Set mChildrenRemovedWhileTransitioning; /** * Creates a new `ReactViewGroup` instance. @@ -170,6 +171,7 @@ private void initView() { mDrawingOrderHelper = null; mBackfaceOpacity = 1.f; mBackfaceVisibility = "visible"; + mChildrenRemovedWhileTransitioning = null; } /* package */ void recycleView() { @@ -405,6 +407,25 @@ public void updateClippingRect() { updateClippingToRect(mClippingRect); } + @Override + public void endViewTransition(View view) { + super.endViewTransition(view); + if (mChildrenRemovedWhileTransitioning != null) { + mChildrenRemovedWhileTransitioning.remove(view.getId()); + } + } + + private Set ensureChildrenRemovedWhileTransitioning() { + if (mChildrenRemovedWhileTransitioning == null) { + mChildrenRemovedWhileTransitioning = new HashSet<>(); + } + return mChildrenRemovedWhileTransitioning; + } + + private boolean isChildRemovedWhileTransitioning(View child) { + return mChildrenRemovedWhileTransitioning != null && mChildrenRemovedWhileTransitioning.contains(child.getId()); + } + private void updateClippingToRect(Rect clippingRect) { Assertions.assertNotNull(mAllChildren); int clippedSoFar = 0; @@ -564,6 +585,12 @@ public void onViewRemoved(View child) { } else { setChildrenDrawingOrderEnabled(false); } + + // The parent might not be null in case the child is transitioning. + if (child.getParent() != null) { + ensureChildrenRemovedWhileTransitioning().add(child.getId()); + } + super.onViewRemoved(child); } @@ -712,7 +739,8 @@ public void run() { */ private boolean isViewClipped(View view) { ViewParent parent = view.getParent(); - if (parent == null) { + + if (parent == null || isChildRemovedWhileTransitioning(view)) { return true; } else { Assertions.assertCondition(parent == this);