<androidx.fragment.app.FragmentContainerView> vs <fragment> jako widok dla NavHost


9

Podczas używania androidx.fragment.app.FragmentContainerViewjako navHost zamiast zwykłej fragmentaplikacji nie można nawigować do miejsca docelowego po zmianie orientacji.

Otrzymuję następujący błąd: java.lang.IllegalStateException: no current navigation node

Czy jest jakiś problem, który powinienem wiedzieć, aby go poprawnie używać, czy też mój sposób używania komponentów nav jest nieprawidłowy?

Proste działanie xml z widokiem:


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

Kod nawigacyjny:

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

Oto repozytorium github, w którym można łatwo odtworzyć błąd: https://github.com/dmytroKarataiev/navHostBug


Musisz umieścić <fragmentw FragmentContainerView.
— EpicPandaForce

Odpowiedzi:


18

no current navigation nodeBłąd występuje, gdy nie ma zestaw wykres i spróbujesz zadzwonić navigate(). Jeśli wystąpi to tylko podczas używania FragmentContainerViewi po zmianie konfiguracji, będzie to związane z tym błędem , który został naprawiony i zaplanowany do wydania w Nawigacji 2.2.0-rc03.

Aby obejść ten problem, możesz albo przełączyć się z powrotem, <fragment>albo usunąć, app:navGraph="@navigation/nav_simple"i zamiast tego zadzwonić navController.setGraph(R.navigation.nav_simple).


W rzeczywistości wypróbowałem to podejście i otrzymałem dokładnie ten sam błąd. Czy byłbyś w stanie sprawdzić repozytorium i spróbować, aby działało z tym podejściem?
— Dmytro Karataiev,

Ponadto ta awaria występuje tylko po zmianie orientacji. Działa cały czas.
— Dmytro Karataiev,

Właściwie myślę, że to nie ten sam błąd, kontroler nawigacyjny nie ma wartości null w moim pytaniu, ale jego tylny stos jest pusty, a wykres jest zerowy.
— Dmytro Karataiev,

Ach, tak, to całkiem ważna informacja. Wygląda na to, że to, czego doświadczasz, to ten drugi problem . Zaktualizowałem swoją odpowiedź, aby omówić, co się dzieje w tym numerze.
— ianhanniballake

Dziękuję idealnie.
— Dmytro Karatajew

0

Nie widzę żadnego wyjaśnienia dlaczego zastąpić Fragment widok z FragmentContainerView . Dlatego dodaj tę odpowiedź:

Jednym z typowych wzorców hostowania fragmentów w działaniu jest użycie FrameLayout. Społeczność Androida robi to od lat, ale teraz to się zmieni. Zespół Androidx wprowadził nowy widok o nazwie FragmentContainerView, aby zrobić to za Ciebie.

Wszystko, co musisz zrobić, to zastąpić FrameLayout FragmentContainerView i wszystko powinno działać od razu, nie musisz nic zmieniać w sposobie obsługi transakcji fragmentów.

Korzyści, jakie tu uzyskano, to poprawiona obsługa tak zwanej kolejności Z dla fragmentów. Oto przykład, którego użyli, ale w zasadzie oznacza to na przykład, że wyjście i przejście między dwoma fragmentami nie będą się na siebie nakładać. Zamiast tego FragmentContainerView rozpocznie animację wyjściową, a następnie animację wejściową.

Jeśli pytasz, czy to może zastąpić tag? wtedy odpowiedź brzmi tak. Wszystko, co musisz zrobić, to dodać Androida: name = "twoja_klasa_nazwa" podczas definiowania FragmentContainerView i użyje FragmentTransaction pod maską do zbudowania i pokazania twojego fragmentu. Oznacza to, że możesz później użyć transakcji fragmentów, aby je zastąpić.

Źródło

Dokumenty na Androida


1
Nie wierzę, że to odpowiada na pytanie, które zadał autor.
— AlgoRyan

To wciąż dobra dodatkowa informacja.
— Rvb84
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.