From f769cba5f0d8f929dbda773f27601606e01a9fe0 Mon Sep 17 00:00:00 2001 From: Krzysztof Piaskowy Date: Tue, 2 Apr 2024 14:49:12 +0200 Subject: [PATCH] fix(Android): Add backward compatibility for prefabs (#2088) ## Description This PR fixes backward compatibility with React Native versions older than 0.71. The issue was caused by using prefabs in the screen transition animation feature. I added a check that makes this feature available since React Native 0.71 Tested against RN versions: - [x] 0.68 - [x] 0.69 - [x] 0.70 - [x] 0.71 - [x] 0.73 Fixes https://github.com/software-mansion/react-native-screens/issues/2082 --------- Co-authored-by: tboba --- android/build.gradle | 50 ++++++++++++++++--- .../com/swmansion/rnscreens/ScreenStack.kt | 4 +- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index c2ecc16236..cafe2dad1f 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -46,6 +46,38 @@ def reactNativeArchitectures() { return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] } +def safeAppExtGet(prop, fallback) { + def appProject = rootProject.allprojects.find { it.plugins.hasPlugin('com.android.application') } + appProject?.ext?.has(prop) ? appProject.ext.get(prop) : fallback +} + +def resolveReactNativeDirectory() { + def reactNativeLocation = safeAppExtGet("REACT_NATIVE_NODE_MODULES_DIR", null) + if (reactNativeLocation != null) { + return file(reactNativeLocation) + } + + def reactNativeFromAppNodeModules = file("${projectDir}/../../react-native") + if (reactNativeFromAppNodeModules.exists()) { + return reactNativeFromAppNodeModules + } + + def reactNativeFromProjectNodeModules = file("${rootProject.projectDir}/../node_modules/react-native") + if (reactNativeFromProjectNodeModules.exists()) { + return reactNativeFromProjectNodeModules + } + + throw new GradleException( + "[RNScreens] Unable to resolve react-native location in node_modules. You should project extension property (in `app/build.gradle`) `REACT_NATIVE_NODE_MODULES_DIR` with path to react-native." + ) +} + +def reactNativeRootDir = resolveReactNativeDirectory() +def reactProperties = new Properties() +file("$reactNativeRootDir/ReactAndroid/gradle.properties").withInputStream { reactProperties.load(it) } +def REACT_NATIVE_VERSION = reactProperties.getProperty("VERSION_NAME") +def REACT_NATIVE_MINOR_VERSION = REACT_NATIVE_VERSION.startsWith("0.0.0-") ? 1000 : REACT_NATIVE_VERSION.split("\\.")[1].toInteger() + android { compileSdkVersion safeExtGet('compileSdkVersion', rnsDefaultCompileSdkVersion) def agpVersion = Version.ANDROID_GRADLE_PLUGIN_VERSION @@ -80,12 +112,14 @@ android { } } } - buildFeatures { - prefab true - } - externalNativeBuild { - cmake { - path "CMakeLists.txt" + if (REACT_NATIVE_MINOR_VERSION >= 71) { + buildFeatures { + prefab true + } + externalNativeBuild { + cmake { + path "CMakeLists.txt" + } } } lintOptions { @@ -146,11 +180,11 @@ repositories { dependencies { implementation 'com.facebook.react:react-native:+' - implementation 'androidx.appcompat:appcompat:1.5.0' + implementation 'androidx.appcompat:appcompat:1.4.2' implementation 'androidx.fragment:fragment:1.3.6' implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' - implementation 'com.google.android.material:material:1.9.0' + implementation 'com.google.android.material:material:1.6.1' implementation "androidx.core:core-ktx:1.8.0" constraints { diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt index 821afd932d..458465ce9f 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStack.kt @@ -337,7 +337,9 @@ class ScreenStack(context: Context?) : ScreenContainer(context) { private fun needsDrawReordering(fragmentWrapper: ScreenFragmentWrapper): Boolean = // On Android sdk 33 and above the animation is different and requires draw reordering. - Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU || + // For React Native 0.70 and lower versions, `Build.VERSION_CODES.TIRAMISU` is not defined yet. + // Hence, we're comparing numerical version here. + Build.VERSION.SDK_INT >= 33 || fragmentWrapper.screen.stackAnimation === StackAnimation.SLIDE_FROM_BOTTOM || fragmentWrapper.screen.stackAnimation === StackAnimation.FADE_FROM_BOTTOM || fragmentWrapper.screen.stackAnimation === StackAnimation.IOS