93

Seems like using the FragmentContainerView doesn't work right out of the box?

<androidx.fragment.app.FragmentContainerView
        class="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/fragment_nav_host"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_app" />

Here's my code using fragment-ktx:1.2.0-rc01 and I'm just always getting this error:

Caused by: java.lang.IllegalStateException: Activity ...MainActivity@797467d does not have a NavController set on 2131296504

Just using <fragment> works and AFAIK, it's just supposed to be replaced by FragmentContainerView.

Am I missing something or was anyone able to use FragmentContainerView as a NavHostFragment?

Many thanks!

Kurt Acosta
  • 2,407
  • 2
  • 14
  • 29

5 Answers5

145

Due to this bug-report: https://issuetracker.google.com/issues/142847973

This is the only way (currently):

val navHostFragment = supportFragmentManager
    .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

(Java):

NavHostFragment navHostFragment =
    (NavHostFragment) getSupportFragmentManager()
        .findFragmentById(R.id.my_nav_host_fragment);
NavController navController = navHostFragment.getNavController();
Alireza Noorali
  • 3,129
  • 2
  • 33
  • 80
Ove Stoerholt
  • 3,843
  • 4
  • 25
  • 33
  • 13
    surely better just to use `fragment`rather than worrying about having to remember to use this workaround? We were seeing crashes but only for some users, weird... – hmac Mar 19 '20 at 09:40
  • 6
    @hmac In the issue linked they discuss why you shouldn't use fragment: https://issuetracker.google.com/issues/142847973#comment15: *The Lint check is there exactly because you absolutely should switch over to FragmentContainerView in all cases.* – Banana Aug 10 '20 at 14:18
  • does not show anything. It's weird I am stuck with using ! – Junia Montana Nov 09 '20 at 04:44
  • 1
    what we have to do with navController, because the variable is unused – Tippu Fisal Sheriff Apr 04 '21 at 07:40
47

August 2020 update

Here is the solution recommended by the official Android documentation.

Kotlin version:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

Java version:

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

I quote the doc:

When creating the NavHostFragment using FragmentContainerView or if manually adding the NavHostFragment to your activity via a FragmentTransaction, attempting to retrieve the NavController in onCreate() of an Activity via Navigation.findNavController(Activity, @IdRes int) will fail. You should retrieve the NavController directly from the NavHostFragment instead.


The bug-report reported by Ove Stoerholt will not be fixed. You can see here the "Won't Fix (Infeasible)" status.

Vince
  • 2,551
  • 1
  • 17
  • 22
  • 3
    While the original task was tagged as "Won't Fix (Infeasible)", they did link to another task so they might plan to fix the issue after all: https://issuetracker.google.com/issues/143145612 – Sharp Oct 25 '20 at 10:04
10

What I did was to wait for the NavHostFragment to inflate its view:

Kotlin:

super.onCreate(savedInstanceState)

// Set up the form and list.
setContentView(R.layout.activity_xxx)

// Set up navigation - action bar and sidebar.
/// Let the navigation view check/uncheck the menu items.
nav_view.post { // wait for NavHostFragment to inflate
    val navController = findNavController()
    nav_view.setupWithNavController(navController)
    nav_view.setNavigationItemSelectedListener(this)
}

Java8 (with lambda):

navigationView.post(() -> { // wait for NavHostFragment to inflate
    navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
    NavigationUI.setupWithNavController(navView, navController);
    navView.setNavigationItemSelectedListener(navItemSelectedListener);
});
hata
  • 11,633
  • 6
  • 46
  • 69
Pnemonic
  • 1,685
  • 17
  • 17
  • I had used `` to avoid the bug. But I was troubled another unknown error. So I found this @Pnemonic's late answer and tried it in order to use ``. The problem has been cleared, thank you! – hata May 25 '20 at 06:36
3

I have the same problem when using kotlin:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

val navController = navHostFragment.navController

Just add it to

setupActionBarWithNavController(navController)

Phani Rithvij
  • 4,030
  • 3
  • 25
  • 60
Galih Al
  • 41
  • 2
-8

using android:name instead of class. works.

<androidx.fragment.app.FragmentContainerView
    android:name="androidx.navigation.fragment.NavHostFragment"
    ...
chihara
  • 1
  • 1