<androidx.fragment.app.FragmentContainerView> vs <fragment> come vista per NavHost


9

Quando si utilizza androidx.fragment.app.FragmentContainerViewcome navHost invece di fragmentun'app normale non è possibile navigare verso una destinazione dopo il cambio di orientamento.

Ottengo un errore seguente: java.lang.IllegalStateException: no current navigation node

C'è un gotcha che dovrei sapere per usarlo correttamente o il mio modo di utilizzare i componenti di navigazione non è corretto?

XML di attività semplice 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" />
...

Codice di navigazione:

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

Ecco un repository github in cui è possibile riprodurre facilmente un bug: https://github.com/dmytroKarataiev/navHostBug


Devi inserire il <fragmentsimbolo a FragmentContainerView.
EpicPandaForce

Risposte:


18

L' no current navigation nodeerrore si verifica quando non è impostato alcun grafico e si tenta di chiamare navigate(). Se si verifica solo quando si utilizza FragmentContainerViewe dopo una modifica della configurazione, ciò sarebbe correlato a questo errore , che è stato risolto e pianificato per il rilascio con Navigation 2.2.0-rc03.

Per aggirare questo problema, è possibile tornare a <fragment>o rimuovere app:navGraph="@navigation/nav_simple"e invece chiamare navController.setGraph(R.navigation.nav_simple).


In realtà ho provato questo approccio e ho avuto esattamente lo stesso errore. Saresti in grado di controllare il repository e provare a farlo funzionare con questo approccio?
Dmytro Karataiev,

Inoltre, questo arresto si verifica solo dopo il cambio di orientamento. Funziona tutte le altre volte.
Dmytro Karataiev,

In realtà penso che questo non sia lo stesso errore, il controller di navigazione non è nullo nella mia domanda, ma il suo stack posteriore è vuoto e il grafico è nullo.
Dmytro Karataiev,

Ah, sì, sono informazioni piuttosto importanti, sembra che quello che stai vivendo sia questo altro problema . Ho aggiornato la mia risposta per discutere cosa sta succedendo in quel problema.
ianhanniballake,

Grazie perfetto.
Dmytro Karataiev il

0

Non vedo alcuna spiegazione per questo sostituire Frammento vista con FragmentContainerView . Ecco perché aggiungi questa risposta:

Uno dei modelli comuni per ospitare frammenti in un'attività è l'uso di un FrameLayout. La comunità Android lo fa da anni, ma questo cambierà ora. Il team androidx ha introdotto questa nuova vista chiamata FragmentContainerView per fare questo per te.

Tutto quello che devi fare è sostituire FrameLayout con FragmentContainerView e tutto dovrebbe funzionare immediatamente, non dovrai cambiare nulla nel modo in cui gestisci le transazioni dei frammenti.

I vantaggi ottenuti qui sono la migliore gestione di ciò che viene chiamato l'ordinamento z per i frammenti. Ecco l'esempio che hanno usato, ma fondamentalmente questo significa, ad esempio, che le uscite e le transizioni di entrata tra due frammenti non si sovrapporranno. Invece questo FragmentContainerView avvia prima l'animazione di uscita, quindi l'animazione di entrata.

Se lo stai chiedendo, è possibile sostituire questo tag? allora la risposta è sì. Tutto quello che devi fare è aggiungere android: name = "your_class_name" quando definisci FragmentContainerView e utilizzerà una transazione di frammenti sotto il cofano per costruire e mostrare il tuo frammento. Ciò significa che è possibile utilizzare le transazioni dei frammenti in un secondo momento per sostituirlo.

fonte

Documenti Android


1
Non credo che questo risponda alla domanda posta dall'autore.
AlgoRyan,

Sono ancora buone informazioni aggiuntive.
Rvb84
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.