safeargs - navigation editor android studio
¿Hay alguna manera de mantener vivo el fragmento al usar BottomNavigationView con el nuevo NavController? (2)
Estoy tratando de usar el nuevo componente de navegación. Uso un BottomNavigationView con el NavController: NavigationUI.setupWithNavController (bottomNavigation, navController)
Pero cuando cambio los fragmentos, cada vez se destruyen / crean, incluso si se utilizaron anteriormente.
¿Hay alguna manera de mantener vivos nuestros enlaces principales a nuestro BottomNavigationView?
No disponible a partir de ahora.
Como solución alternativa, puede almacenar todos los datos obtenidos en el modelo de vista y tener esos datos fácilmente disponibles cuando vuelva a crear el fragmento. Asegúrese de obtener la vista utilizando el contexto de actividades.
Puede usar LiveData para hacer que sus datos sean conscientes del ciclo de vida.
Prueba esto.
Navegador
Crear navegador personalizado.
@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)
}
}
NavHostFragment
Crea NavHostFragment personalizado.
class CustomNavHostFragment: NavHostFragment() {
override fun createFragmentNavigator(): Navigator<out FragmentNavigator.Destination> {
return CustomNavigator(requireContext(), childFragmentManager, id)
}
}
navegación.xml
Use una etiqueta personalizada en lugar de una etiqueta de fragmento.
<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>
diseño de la actividad
Use CustomNavHostFragment en lugar 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>
Actualizar
Creé proyecto de muestra. link
No creo NavHostFragment personalizado. Yo uso navController.navigatorProvider += navigator
.