<androidx.fragment.app.FragmentContainerView> vs <fragment> comme vue pour un NavHost

9

Lors de l'utilisation en androidx.fragment.app.FragmentContainerViewtant que navHost au lieu d'une fragmentapplication standard, il n'est pas possible de naviguer vers une destination après un changement d'orientation.

J'obtiens une erreur suivante: java.lang.IllegalStateException: no current navigation node

Existe-t-il un problème que je devrais connaître pour l'utiliser correctement ou ma façon d'utiliser les composants de navigation est-elle incorrecte?

Activité simple xml avec une vue:


...
    <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" />
...

Code de navigation:

<?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>

Voici un dépôt github où vous pouvez facilement reproduire un bug: https://github.com/dmytroKarataiev/navHostBug

Dmytro Karataiev
la source
Vous devez mettre le <fragmentdans un fichier FragmentContainerView.
EpicPandaForce

Réponses:

18

L' no current navigation nodeerreur se produit lorsqu'il n'y a pas de jeu de graphiques et que vous essayez d'appeler navigate(). Si cela ne se produit que lorsque vous utilisez FragmentContainerViewet après un changement de configuration, cela serait lié à ce bogue , qui est corrigé et prévu pour la version avec Navigation 2.2.0-rc03.

Pour contourner ce problème, vous pouvez revenir à <fragment>ou supprimer app:navGraph="@navigation/nav_simple"et appeler à la place navController.setGraph(R.navigation.nav_simple).

ianhanniballake
la source
J'ai en fait essayé cette approche et j'ai eu exactement la même erreur. Pourriez-vous consulter le dépôt et essayer de le faire fonctionner avec cette approche?
Dmytro Karataiev
En outre, ce plantage se produit uniquement après un changement d'orientation. Cela fonctionne toutes les autres fois.
Dmytro Karataiev
En fait, je pense que ce n'est pas la même erreur, le contrôleur de navigation n'est pas nul dans ma question, mais sa pile arrière est vide et le graphique est nul.
Dmytro Karataiev
Ah, oui, ce sont des informations assez importantes, on dirait que ce que vous vivez est cet autre problème . J'ai mis à jour ma réponse pour discuter de ce qui se passe dans ce problème.
ianhanniballake
Merci, parfait.
Dmytro Karataiev
0

Je ne vois pas d'explication pourquoi remplacer Fragment vue avec FragmentContainerView . C'est pourquoi ajoutez cette réponse:

L'un des modèles courants pour héberger des fragments dans une activité est d'utiliser un FrameLayout. La communauté Android le fait depuis des années, mais cela va changer maintenant. L'équipe androidx a introduit cette nouvelle vue appelée FragmentContainerView pour le faire pour vous.

Tout ce que vous avez à faire est de remplacer votre FrameLayout par FragmentContainerView et tout devrait fonctionner hors de la boîte, vous n'aurez pas besoin de changer quoi que ce soit dans la façon dont vous gérez les transactions de fragments.

Les avantages obtenus ici sont la gestion améliorée de ce que l'on appelle l'ordre z des fragments. Voici l'exemple qu'ils ont utilisé, mais cela signifie, par exemple, que les transitions de sortie et d'entrée entre deux fragments ne se chevaucheront pas. Au lieu de cela, FragmentContainerView va commencer l'animation de sortie d'abord, puis l'animation d'entrée.

Si vous demandez, cela peut-il remplacer la balise? alors la réponse est oui. Tout ce que vous avez à faire est d'ajouter android: name = "your_class_name" lors de la définition de FragmentContainerView et il utilisera une FragmentTransaction sous le capot pour construire et afficher votre fragment. Cela signifie que vous pouvez utiliser des transactions fragmentées ultérieurement pour le remplacer.

La source

Documents Android

Michalsx
la source
1
Je ne pense pas que cela réponde à la question posée par l'auteur.
AlgoRyan
Ce sont toujours de bonnes informations supplémentaires.
Rvb84 Il y a