<androidx.fragment.app.FragmentContainerView> vs <fragment> als Ansicht für einen NavHost

9

Bei Verwendung androidx.fragment.app.FragmentContainerViewals navHost anstelle einer normalen fragmentApp kann nach einer Änderung der Ausrichtung nicht zu einem Ziel navigiert werden.

Ich erhalte folgende Fehlermeldung: java.lang.IllegalStateException: no current navigation node

Gibt es ein Problem, über das ich Bescheid wissen sollte, um es richtig zu verwenden, oder ist meine Art, Navigationskomponenten zu verwenden, falsch?

Einfache Aktivität XML mit einer Ansicht:


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

Navigationscode:

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

Hier ist ein Github-Repo, in dem Sie einen Fehler leicht reproduzieren können: https://github.com/dmytroKarataiev/navHostBug

Dmytro Karataiev
quelle
Sie müssen das <fragmentin ein setzen FragmentContainerView.
EpicPandaForce

Antworten:

18

Der no current navigation nodeFehler tritt auf, wenn kein Diagrammsatz vorhanden ist und Sie versuchen aufzurufen navigate(). Wenn es nur bei der Verwendung FragmentContainerViewund nach einer Konfigurationsänderung auftritt , hängt dies mit diesem Fehler zusammen , der behoben und für die Veröffentlichung mit Navigation 2.2.0-rc03 geplant ist.

Um dieses Problem zu umgehen, können Sie entweder zurückschalten <fragment>oder entfernen app:navGraph="@navigation/nav_simple"und stattdessen aufrufen navController.setGraph(R.navigation.nav_simple).

ianhanniballake
quelle
Ich habe diesen Ansatz tatsächlich ausprobiert und genau den gleichen Fehler erhalten. Könnten Sie das Repo überprüfen und versuchen, es mit diesem Ansatz zum Laufen zu bringen?
Dmytro Karataiev
Dieser Absturz tritt auch erst nach einer Änderung der Ausrichtung auf. Es funktioniert alle anderen Male.
Dmytro Karataiev
Ich denke tatsächlich, dass dies nicht der gleiche Fehler ist, der Navigationscontroller ist in meiner Frage nicht null, aber sein hinterer Stapel ist leer und das Diagramm ist null.
Dmytro Karataiev
Ah, ja, das sind ziemlich wichtige Informationen. Klingt so, als ob Sie dieses andere Problem erleben . Ich habe meine Antwort aktualisiert, um zu besprechen, was in dieser Ausgabe vor sich geht.
Ianhanniballake
Danke, perfekt.
Dmytro Karataiev
0

Ich sehe keine Erklärung, warum die Fragmentansicht durch FragmentContainerView ersetzt wird . Fügen Sie deshalb diese Antwort hinzu:

Eines der gängigen Muster zum Hosten von Fragmenten in einer Aktivität ist die Verwendung eines FrameLayout. Die Android-Community macht das schon seit Jahren, aber das wird sich jetzt ändern. Das Androidx-Team hat diese neue Ansicht namens FragmentContainerView eingeführt, um dies für Sie zu tun.

Alles, was Sie tun müssen, ist, Ihr FrameLayout durch FragmentContainerView zu ersetzen. Alles sollte sofort funktionieren. Sie müssen nichts an der Art und Weise ändern, wie Sie Fragmenttransaktionen abwickeln.

Die hier erzielten Vorteile sind die verbesserte Handhabung der sogenannten Z-Reihenfolge für Fragmente. Hier ist das Beispiel, das sie verwendet haben, aber im Grunde bedeutet dies zum Beispiel, dass sich die Übergänge Exit und Enter zwischen zwei Fragmenten nicht überlappen. Stattdessen startet diese FragmentContainerView zuerst die Exit-Animation und dann die Enter-Animation.

Wenn Sie fragen, kann dies Tag ersetzen? dann lautet die Antwort ja. Alles was Sie tun müssen, ist android: name = "your_class_name" hinzuzufügen, wenn Sie FragmentContainerView definieren, und es wird eine FragmentTransaction unter der Haube verwenden, um Ihr Fragment zu erstellen und anzuzeigen. Dies bedeutet, dass Sie Fragmenttransaktionen später verwenden können, um sie zu ersetzen.

Quelle

Android-Dokumente

Michalsx
quelle
1
Ich glaube nicht, dass dies die Frage beantwortet, die der Autor gestellt hat.
AlgoRyan
Es sind immer noch gute Zusatzinformationen.
Rvb84