From a6f2ba35e2314425e4674cb9101faf7d3d71d310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Du=C5=BCy?= <91994767+alduzy@users.noreply.github.com> Date: Tue, 20 Aug 2024 15:49:12 +0200 Subject: [PATCH] fix(Android): incorrect childCount in removeViewAt when using flatlist on fabric (#2307) ## Description This PR intents to fix the crash when navigating back from a screen with FlatList on the new architecture. The crash was caused by miscalculated `childCount` of the list. Earlier on I found out that setting the [removeClippedSubviews](https://reactnative.dev/docs/flatlist#removeclippedsubviews) option to false (defaults to true on Android) in the FlatList fixes the problem. This PR is rather a quick fix with an extra condition, that adds simple views in place of the miscalculated ones in `startTransitionRecursive` function if there's a FlatList with `removeClippedSubviews` option set. Fixes #2282. ## Changes - added `Test2282.tsx` repro - added extra condition in `startTransitionRecursive` function ## Test code and steps to reproduce - added `Test2282.tsx` repro ## Checklist - [x] Ensured that CI passes --- .../java/com/swmansion/rnscreens/Screen.kt | 10 ++++++ apps/src/tests/Test2282.tsx | 32 +++++++++++++++++++ apps/src/tests/index.ts | 1 + 3 files changed, 43 insertions(+) create mode 100644 apps/src/tests/Test2282.tsx diff --git a/android/src/main/java/com/swmansion/rnscreens/Screen.kt b/android/src/main/java/com/swmansion/rnscreens/Screen.kt index a601100985..01a7bc5ef1 100644 --- a/android/src/main/java/com/swmansion/rnscreens/Screen.kt +++ b/android/src/main/java/com/swmansion/rnscreens/Screen.kt @@ -19,6 +19,7 @@ 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.ReactScrollView import com.google.android.material.bottomsheet.BottomSheetBehavior import com.swmansion.rnscreens.events.HeaderHeightChangeEvent import com.swmansion.rnscreens.events.SheetDetentChangedEvent @@ -384,6 +385,15 @@ class Screen( startTransitionRecursive(child.toolbar) } 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/issues/2282 + if (it is ReactScrollView && it.removeClippedSubviews) { + for (j in 0 until child.childCount) { + child.addView(View(context)) + } + } startTransitionRecursive(child) } } diff --git a/apps/src/tests/Test2282.tsx b/apps/src/tests/Test2282.tsx new file mode 100644 index 0000000000..6ee9b61b66 --- /dev/null +++ b/apps/src/tests/Test2282.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { FlatList, Button, Text } from 'react-native'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { NavigationContainer } from '@react-navigation/native'; + +const Stack = createNativeStackNavigator(); + +const First = ({ navigation }: any) => ( +