J'essaie d'utiliser le nouveau composant de navigation. J'utilise BottomNavigationView avec le navController: NavigationUI.setupWithNavController (bottomNavigation, navController)
Mais lorsque je change de fragment, il est à chaque fois détruit/créé, même s’il était utilisé auparavant.
Existe-t-il un moyen de garder en vie nos principaux fragments liés à notre BottomNavigationView?
Essaye ça.
Créer un navigateur personnalisé.
@Navigator.Name("custom_fragment") // Use as custom tag at navigation.xml
class CustomNavigator(
private val context: Context,
private val manager: FragmentManager,
private val containerId: Int
) : FragmentNavigator(context, manager, containerId) {
override fun navigate(destination: Destination, args: Bundle?, navOptions: NavOptions?) {
val tag = destination.id.toString()
val transaction = manager.beginTransaction()
val currentFragment = manager.primaryNavigationFragment
if (currentFragment != null) {
transaction.detach(currentFragment)
}
var fragment = manager.findFragmentByTag(tag)
if (fragment == null) {
fragment = destination.createFragment(args)
transaction.add(containerId, fragment, tag)
} else {
transaction.attach(fragment)
}
transaction.setPrimaryNavigationFragment(fragment)
transaction.setReorderingAllowed(true)
transaction.commit()
dispatchOnNavigatorNavigated(destination.id, BACK_STACK_DESTINATION_ADDED)
}
}
Créez un NavHostFragment personnalisé.
class CustomNavHostFragment: NavHostFragment() {
override fun createFragmentNavigator(): Navigator<out FragmentNavigator.Destination> {
return CustomNavigator(requireContext(), childFragmentManager, id)
}
}
Utilisez une balise personnalisée au lieu d'une balise fragment.
<navigation xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto" Android:id="@+id/navigation"
app:startDestination="@id/navigation_first">
<custom_fragment
Android:id="@+id/navigation_first"
Android:name="com.example.sample.FirstFragment"
Android:label="FirstFragment" />
<custom_fragment
Android:id="@+id/navigation_second"
Android:name="com.example.sample.SecondFragment"
Android:label="SecondFragment" />
</navigation>
Utilisez CustomNavHostFragment au lieu de NavHostFragment.
<androidx.constraintlayout.widget.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<fragment
Android:id="@+id/nav_Host_fragment"
Android:name="com.example.sample.CustomNavHostFragment"
Android:layout_width="0dp"
Android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/navigation" />
<com.google.Android.material.bottomnavigation.BottomNavigationView
Android:id="@+id/bottom_navigation"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="@menu/navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
J'ai créé un exemple de projet. lien
Je ne crée pas NavHostFragment personnalisé. J'utilise navController.navigatorProvider += navigator
.
Non disponible à partir de maintenant.
En guise de solution de contournement, vous pouvez stocker toutes vos données extraites dans le modèle d'affichage et les disposer facilement lorsque vous recréez le fragment. Assurez-vous d'obtenir la vue en utilisant le contexte des activités.
Vous pouvez utiliser LiveData pour rendre vos données observables sensibles au cycle de vie des données.