<androidx.fragment.app.FragmentContainerView> vs <fragment> como una vista para un NavHost

9

Cuando se usa androidx.fragment.app.FragmentContainerViewcomo navHost en lugar de una fragmentaplicación normal, no puede navegar a un destino después del cambio de orientación.

Me sale el siguiente error: java.lang.IllegalStateException: no current navigation node

¿Hay algún problema que deba saber para usarlo correctamente o mi forma de usar los componentes de navegación es incorrecta?

Actividad simple xml con una vista:


...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/nav_simple" />
...

Código de navegación:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_legislator.xml"
    app:startDestination="@id/initialFragment">

    <fragment
        android:id="@+id/initialFragment"
        android:name="com.example.fragmenttag.InitialFragment"
        android:label="Initial Fragment"
        tools:layout="@layout/initial_fragment">
        <action
            android:id="@+id/action_initialFragment_to_destinationFragment"
            app:destination="@id/destinationFragment" />
    </fragment>
    <fragment
        android:id="@+id/destinationFragment"
        android:name="com.example.fragmenttag.DestinationFragment"
        android:label="Destination Fragment"
        tools:layout="@layout/destination_fragment" />

</navigation>

Aquí hay un repositorio de Github donde puede reproducir fácilmente un error: https://github.com/dmytroKarataiev/navHostBug

Dmytro Karataiev
fuente
Necesitas poner el <fragmenta FragmentContainerView.
EpicPandaForce

Respuestas:

18

El no current navigation nodeerror ocurre cuando no hay un conjunto de gráficos e intenta llamar navigate(). Si solo ocurre cuando está usando FragmentContainerViewy después de un cambio de configuración, esto estaría relacionado con este error , que está solucionado y programado para su lanzamiento con Navigation 2.2.0-rc03.

Para solucionar este problema, puede volver a cambiar <fragment>o eliminar app:navGraph="@navigation/nav_simple"y, en su lugar, llamar navController.setGraph(R.navigation.nav_simple).

ianhanniballake
fuente
En realidad probé este enfoque y obtuve exactamente el mismo error. ¿Sería capaz de consultar el repositorio e intentar que funcione con este enfoque?
Dmytro Karataiev
Además, este bloqueo ocurre solo después del cambio de orientación. Funciona todas las otras veces.
Dmytro Karataiev
De hecho, creo que este no es el mismo error, el controlador de navegación no es nulo en mi pregunta, pero su pila posterior está vacía y el gráfico es nulo.
Dmytro Karataiev
Ah, sí, esa es información bastante importante. Parece que lo que estás experimentando es este otro problema . He actualizado mi respuesta para discutir lo que está sucediendo en ese tema.
ianhanniballake
Gracias perfecto
Dmytro Karataiev
0

No veo ninguna explicación de por qué reemplazar Fragment view con FragmentContainerView . Es por eso que agregue esta respuesta:

Uno de los patrones comunes para alojar fragmentos en una actividad es usar un FrameLayout. La comunidad de Android ha estado haciendo esto durante años, pero esto va a cambiar ahora. El equipo de androidx presentó esta nueva vista llamada FragmentContainerView para hacer esto por usted.

Todo lo que tiene que hacer es reemplazar su FrameLayout con FragmentContainerView y todo debería funcionar de inmediato, no necesitará cambiar nada en la forma en que maneja las transacciones fragmentadas.

Los beneficios obtenidos aquí es el manejo mejorado de lo que se llama el orden z para los fragmentos. Este es el ejemplo que usaron, pero básicamente esto significa, por ejemplo, que las transiciones de salida e ingreso entre dos fragmentos no se superpondrán entre sí. En cambio, este FragmentContainerView va a comenzar la animación de salida primero y luego la animación de entrada.

Si está preguntando, ¿puede esto reemplazar la etiqueta? Entonces la respuesta es sí. Todo lo que tiene que hacer es agregar android: name = "your_class_name" al definir FragmentContainerView y usará una FragmentTransaction debajo del capó para construir y mostrar su fragmento. Esto significa que puede usar transacciones fragmentarias más adelante para reemplazarlo.

Fuente

Documentos de Android

Michalsx
fuente
1
No creo que esto responda la pregunta que estaba haciendo el autor.
AlgoRyan
Todavía es buena información adicional.
Rvb84