24

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
  • 666
  • 1
  • 7
  • 12

4 Answers4

30

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).

ianhanniballake
  • 155,909
  • 19
  • 351
  • 362
21

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

Michalsx
  • 2,515
  • 3
  • 23
  • 39
  • 3
    I don't believe this answers the question the author was asking. – AlgoRyan Feb 20 '20 at 23:55
  • Thanks! See also https://stackoverflow.com/questions/60009473/classnotfoundexception-when-using-androidx-fragment-app-fragmentcontainerview/64225308 for adding rules in `proguard-rules.pro`. – CoolMind Oct 06 '20 at 12:03
  • 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. – iam thadiyan Jan 16 '21 at 15:15
  • Regarding android:name="your_class_name" what class should "your_class_name" be? the hosting Activity or a Fragment? – ProjectDelta Jan 17 '21 at 02:31
  • The original question is about , not . – alekop Feb 26 '21 at 19:10
0
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    return inflater.inflate(R.layout.frag_splash, container, false)
}

Maybe you forgot the 3rd "false" parameter above. Only this three parameters onCreateView fun can be accept.

android developer website

pic from : https://developer.android.com/reference/androidx/fragment/app/FragmentContainerView

0
// drawer layout that I pass is the id of the layout in the activity from which I move to fragment//

SacnFragment sacnFragment = new SacnFragment();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.replace(R.id.drawer_layout, sacnFragment);
    transaction.addToBackStack(null);
    transaction.commit();
Suraj Rao
  • 28,186
  • 10
  • 88
  • 94