Skip to content
23 changes: 14 additions & 9 deletions android/src/main/java/com/swmansion/rnscreens/Screen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import com.facebook.react.uimanager.PixelUtil
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.UIManagerModule
import com.facebook.react.uimanager.events.EventDispatcher
import com.facebook.react.views.scroll.ReactHorizontalScrollView
import com.facebook.react.views.scroll.ReactScrollView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.shape.CornerFamily
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import com.swmansion.rnscreens.events.HeaderHeightChangeEvent
import com.swmansion.rnscreens.events.SheetDetentChangedEvent
import com.swmansion.rnscreens.ext.isInsideScrollViewWithRemoveClippedSubviews
import com.swmansion.rnscreens.ext.isRemovingClippedSubviews
import java.lang.ref.WeakReference

@SuppressLint("ViewConstructor") // Only we construct this view, it is never inflated.
Expand Down Expand Up @@ -378,7 +380,10 @@ class Screen(
}
}

private fun startTransitionRecursive(parent: ViewGroup?) {
private fun startTransitionRecursive(
parent: ViewGroup?,
isPossiblyRemovedClippedSubview: Boolean = true,
) {
parent?.let {
for (i in 0 until it.childCount) {
val child = it.getChildAt(i)
Expand All @@ -396,19 +401,19 @@ class Screen(
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)
startTransitionRecursive(child, isPossiblyRemovedClippedSubview || it.isRemovingClippedSubviews)
}
if (child is ViewGroup) {
// The children are miscounted when there's a FlatList with
// removeClippedSubviews set to true (default).
// We add a simple view for each item in the list to make it work as expected.
// See https://github.com/software-mansion/react-native-screens/pull/2383
if (child.isInsideScrollViewWithRemoveClippedSubviews()) {
// The children are miscounted when there's removeClippedSubviews prop
// set to true (which is the default for FlatLists).
// We 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 (isPossiblyRemovedClippedSubview && child !is ReactScrollView && child !is ReactHorizontalScrollView) {
for (j in 0 until child.childCount) {
child.addView(View(context))
}
}
startTransitionRecursive(child)
startTransitionRecursive(child, isPossiblyRemovedClippedSubview || it.isRemovingClippedSubviews)
}
}
}
Expand Down
26 changes: 6 additions & 20 deletions android/src/main/java/com/swmansion/rnscreens/ext/ViewExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.view.View
import android.view.ViewGroup
import com.facebook.react.views.scroll.ReactHorizontalScrollView
import com.facebook.react.views.scroll.ReactScrollView
import com.swmansion.rnscreens.ScreenStack

internal fun View.parentAsView() = this.parent as? View

Expand Down Expand Up @@ -34,23 +33,10 @@ internal fun View.maybeBgColor(): Int? {
return null
}

internal fun View.isInsideScrollViewWithRemoveClippedSubviews(): Boolean {
if (this is ReactHorizontalScrollView || this is ReactScrollView) {
return false
}
var parentView = this.parent
while (parentView is ViewGroup && parentView !is ScreenStack) {
when (parentView) {
is ReactHorizontalScrollView -> {
return parentView.removeClippedSubviews
}
is ReactScrollView -> {
return parentView.removeClippedSubviews
}
else -> {
parentView = parentView.parent
}
internal val View.isRemovingClippedSubviews: Boolean
get() =
when (this) {
is ReactHorizontalScrollView -> removeClippedSubviews
is ReactScrollView -> removeClippedSubviews
else -> false
}
}
return false
}
7 changes: 6 additions & 1 deletion apps/src/tests/Test2282.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,13 @@ function Home({ navigation }: any) {

function ListScreen() {
return (
<View style={{ flex: 1, backgroundColor: 'slateblue' }}>
<View
style={{ flex: 1, backgroundColor: 'slateblue' }}
removeClippedSubviews>
<ParentFlatlist />
<View removeClippedSubviews>
<View style={{ backgroundColor: 'pink', width: '100%', height: 50 }} />
</View>
<ParentFlatlist horizontal />
</View>
);
Expand Down