diff --git a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.kt b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.kt index 46b437ea07..5fbec0223e 100644 --- a/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.kt +++ b/Example/android/app/src/main/java/com/swmansion/rnscreens/example/MainActivity.kt @@ -5,6 +5,7 @@ import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled import com.facebook.react.defaults.DefaultReactActivityDelegate +import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory class MainActivity : ReactActivity() { @@ -22,6 +23,7 @@ class MainActivity : ReactActivity() { DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(null) + supportFragmentManager.fragmentFactory = RNScreensFragmentFactory() + super.onCreate(savedInstanceState) } } diff --git a/FabricExample/android/app/src/main/java/com/fabricexample/MainActivity.kt b/FabricExample/android/app/src/main/java/com/fabricexample/MainActivity.kt index 235fa3d487..55745c2121 100644 --- a/FabricExample/android/app/src/main/java/com/fabricexample/MainActivity.kt +++ b/FabricExample/android/app/src/main/java/com/fabricexample/MainActivity.kt @@ -1,9 +1,11 @@ package com.fabricexample +import android.os.Bundle import com.facebook.react.ReactActivity import com.facebook.react.ReactActivityDelegate import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled import com.facebook.react.defaults.DefaultReactActivityDelegate +import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory class MainActivity : ReactActivity() { @@ -19,4 +21,9 @@ class MainActivity : ReactActivity() { */ override fun createReactActivityDelegate(): ReactActivityDelegate = DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) + + override fun onCreate(savedInstanceState: Bundle?) { + supportFragmentManager.fragmentFactory = RNScreensFragmentFactory() + super.onCreate(savedInstanceState) + } } diff --git a/README.md b/README.md index 0538f6bb9f..34ed488bc8 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Please note that the override code should not be placed inside `MainActivityDele ```java import android.os.Bundle; +import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory; public class MainActivity extends ReactActivity { @@ -43,7 +44,8 @@ public class MainActivity extends ReactActivity { //react-native-screens override @Override protected void onCreate(Bundle savedInstanceState) { - super.onCreate(null); + getSupportFragmentManager().setFragmentFactory(new RNScreensFragmentFactory()); + super.onCreate(savedInstanceState); } public static class MainActivityDelegate extends ReactActivityDelegate { @@ -59,6 +61,7 @@ public class MainActivity extends ReactActivity { ```kotlin import android.os.Bundle; +import com.swmansion.rnscreens.fragment.restoration.RNScreensFragmentFactory; class MainActivity: ReactActivity() { @@ -66,6 +69,7 @@ class MainActivity: ReactActivity() { //react-native-screens override override fun onCreate(savedInstanceState: Bundle?) { + supportFragmentManager.fragmentFactory = RNScreensFragmentFactory() super.onCreate(null); } } diff --git a/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/AutoRemovingFragment.kt b/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/AutoRemovingFragment.kt new file mode 100644 index 0000000000..c475e86ea5 --- /dev/null +++ b/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/AutoRemovingFragment.kt @@ -0,0 +1,38 @@ +package com.swmansion.rnscreens.fragment.restoration + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment + +/** +* This class serves as a workaround to https://github.com/software-mansion/react-native-screens/issues/17. +* +* This fragment, when attached to the fragment manager & its state is progressed +* to `ON_CREATED`, attempts to detach itself from the parent fragment manager +* as soon as possible. +* +* Instances of this type should be created in place of regular screen fragments +* when Android restores fragments after activity / application restart. +* If done so, it's behaviour can prevent duplicated fragment instances, +* as React will render new ones on activity restart. +*/ +class AutoRemovingFragment : Fragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // This is the first moment where we have access to non-null parent fragment manager, + // so that we can remove the fragment from the hierarchy. + parentFragmentManager + .beginTransaction() + .remove(this) + .commitAllowingStateLoss() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle?, + ): View? = null +} diff --git a/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/RNScreensFragmentFactory.kt b/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/RNScreensFragmentFactory.kt new file mode 100644 index 0000000000..9eede9b005 --- /dev/null +++ b/android/src/main/java/com/swmansion/rnscreens/fragment/restoration/RNScreensFragmentFactory.kt @@ -0,0 +1,13 @@ +package com.swmansion.rnscreens.fragment.restoration + +class RNScreensFragmentFactory : androidx.fragment.app.FragmentFactory() { + override fun instantiate( + classLoader: ClassLoader, + className: String, + ): androidx.fragment.app.Fragment = + if (className.startsWith(com.swmansion.rnscreens.BuildConfig.LIBRARY_PACKAGE_NAME)) { + AutoRemovingFragment() + } else { + super.instantiate(classLoader, className) + } +}