视图为 NavHostFragment

看起来使用 FragmentContainerView不是立竿见影的吗?

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

下面是我使用 fragment-ktx:1.2.0-rc01编写的代码,我总是得到这个错误:

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

只要使用 <fragment>工程和 AFAIK,它只是应该被取代的 FragmentContainerView

是我漏掉了什么,还是有人能够使用 FragmentContainerView作为 NavHostFragment

非常感谢!

40014 次浏览

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();

using android:name instead of class. works.

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

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);
});

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.

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)