<androidx.fragment.app.FragmentContainerView> vs <fragment> as a view for a NavHost

27,543

Solution 1

The no current navigation node error occurs when there's no graph set and you attempt to call navigate(). If it only occurs when you're using FragmentContainerView and after a configuration change, then this would be related to this bug, which is fixed and scheduled for release with Navigation 2.2.0-rc03.

To work around this issue, you can either switch back to <fragment> or remove app:navGraph="@navigation/nav_simple" and instead call navController.setGraph(R.navigation.nav_simple).

Solution 2

I do not see any explanation why replace Fragment view with FragmentContainerView. This is why add this answer:

One of the common patterns to host fragments in an activity is to use a FrameLayout. The Android community have been doing this for years but this is going to change now. The androidx team introduced this new view called FragmentContainerView to do this for you.

All you have to do is replace your FrameLayout with FragmentContainerView and everything should work out of the box, you won’t need to change anything on the way you handle fragment transactions.

The benefits gained here is the improved handling of what’s called the z-ordering for fragments. Here’s the example they used, but basically this means , for example, that the exit and enter transitions between two fragments will not overlap each other. Instead this FragmentContainerView is going to start the exit animation first then the enter animation.

If you are asking can this replace tag? then the answer is yes. All you have to do is to add android:name="your_class_name" when defining FragmentContainerView and it will use a FragmentTransaction under the hood to build and show your fragment. This mean you can use fragment transactions later on to replace it.

Source

Android Docs

Share:
27,543
Dmytro Karataiev
Author by

Dmytro Karataiev

Updated on March 11, 2021

Comments

  • Dmytro Karataiev
    Dmytro Karataiev about 3 years

    When using androidx.fragment.app.FragmentContainerView as a navHost instead of a regular fragment app is not able to navigate to a destination after orientation change.

    I get a following error: java.lang.IllegalStateException: no current navigation node

    Is there a gotcha that I should know about to use it properly or is my way of using nav components is incorrect?

    Simple activity xml with a view:

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

    Navigation code:

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

    Here is a github repo where you can easily reproduce a bug: https://github.com/dmytroKarataiev/navHostBug

  • Dmytro Karataiev
    Dmytro Karataiev over 4 years
    I actually tried this approach and I got exactly the same error. Would you be able to check out the repo and try to make it work with this approach?
  • Dmytro Karataiev
    Dmytro Karataiev over 4 years
    Also, this crash happens only after orientation change. It works all the other times.
  • Dmytro Karataiev
    Dmytro Karataiev over 4 years
    I actually think this is not the same error, nav controller is not null in my question, but its back stack is empty and the graph is null.
  • ianhanniballake
    ianhanniballake over 4 years
    Ah, yeah, that's pretty important information, Sounds like what you're experiencing is this other issue. I've updated my answer to discuss what is going on in that issue.
  • Dmytro Karataiev
    Dmytro Karataiev over 4 years
    Thank you, perfect.
  • ror
    ror over 4 years
    Just stumbled upon this as well. Thank you.
  • G_comp
    G_comp over 4 years
    I was getting an IllegalStateException You must call setGraph() before calling getGraph() and switching to <fragment> solved my problem. Thank you!
  • ianhanniballake
    ianhanniballake over 4 years
    @G_comp - Navigation 2.2.0-rc03 is out now, so I'd certainly recommend trying it again and ensuring that it is fixed before the stable release
  • AlgoRyan
    AlgoRyan about 4 years
    I don't believe this answers the question the author was asking.
  • Robert
    Robert about 4 years
    This should be explained somewhere in official codelab! Or am I miss it?
  • CoolMind
    CoolMind over 3 years
    Thanks! See also stackoverflow.com/questions/60009473/… for adding rules in proguard-rules.pro.
  • iam thadiyan
    iam thadiyan over 3 years
    Thanks a lot for this answer. This helps with the issue I face now. It doesn't solve it. But I know more about the FrameLayout vs FragmentContainerView hell.
  • ProjectDelta
    ProjectDelta over 3 years
    Regarding android:name="your_class_name" what class should "your_class_name" be? the hosting Activity or a Fragment?
  • alekop
    alekop about 3 years
    The original question is about <fragment>, not <FrameLayout>.