From cf4ab4644e601ffbb4a52f07aec54c25aa04ac15 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Nov 2024 13:28:48 +0100 Subject: [PATCH 1/2] Patch attempt - 1 --- .../java/com/swmansion/rnscreens/Screen.kt | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt index df99973234..bb424e4de6 100644 --- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt +++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt @@ -17,6 +17,7 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.facebook.react.bridge.GuardedRunnable import com.facebook.react.bridge.ReactContext import com.facebook.react.uimanager.PixelUtil +import com.facebook.react.uimanager.ReactClippingViewGroup import com.facebook.react.uimanager.UIManagerHelper import com.facebook.react.uimanager.UIManagerModule import com.facebook.react.uimanager.events.EventDispatcher @@ -383,6 +384,7 @@ class Screen( parent?.let { for (i in 0 until it.childCount) { val child = it.getChildAt(i) + if (parent is SwipeRefreshLayout && child is ImageView) { // SwipeRefreshLayout class which has CircleImageView as a child, // does not handle `startViewTransition` properly. @@ -394,20 +396,36 @@ class Screen( } else { child?.let { view -> it.startViewTransition(view) } } + if (child is ScreenStackHeaderConfig) { // we want to start transition on children of the toolbar too, // which is not a child of ScreenStackHeaderConfig startTransitionRecursive(child.toolbar) } + if (child is ViewGroup) { + // We mark the children as transitioning, but some of them might be clipped // The children are miscounted when there's removeClippedSubviews prop // set to true (which is the default for FlatLists). // Unless the child is a ScrollView it's safe to assume that it's true // and add a simple view for each possibly clipped item to make it work as expected. // See https://github.com/software-mansion/react-native-screens/pull/2495 - if (child !is ReactScrollView && child !is ReactHorizontalScrollView) { - for (j in 0 until child.childCount) { - child.addView(View(context)) + + if (child is ReactClippingViewGroup && + child.removeClippedSubviews && + child !is ReactScrollView && + child !is ReactHorizontalScrollView + ) { + // We need to workaround the issue until our changes land in core. + // Some views do not accept any children or have set amount and they throw + // when we want to brute-forcefully manipulate that. + // Is this ugly? Very. Do we have better option before changes land in core? + // I'm not aware of any. + try { + for (j in 0 until child.childCount) { + child.addView(View(context)) + } + } catch (_: Exception) { } } startTransitionRecursive(child) From bc0929c221970136d947d98b075fd3549c95e053 Mon Sep 17 00:00:00 2001 From: Kacper Kafara Date: Thu, 21 Nov 2024 13:34:50 +0100 Subject: [PATCH 2/2] Leftover comment --- android/src/main/java/com/swmansion/rnscreens/Screen.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt index bb424e4de6..c2761f5f4e 100644 --- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt +++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt @@ -404,7 +404,6 @@ class Screen( } if (child is ViewGroup) { - // We mark the children as transitioning, but some of them might be clipped // The children are miscounted when there's removeClippedSubviews prop // set to true (which is the default for FlatLists). // Unless the child is a ScrollView it's safe to assume that it's true