我正在将Android导航组件与底部导航一起使用,棉绒给出了有关将<fragment>
标记替换为FragmentContainerView
的警告,但是如果替换findNavController
无效,则会出现以下错误没有设置NavController
片段
<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:navGraph="@navigation/mobile_navigation" />
活动
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_classes, R.id.navigation_schedule, R.id.navigation_settings
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
答案 0 :(得分:4)
根据this issue,当使用FragmentContainerView
时,您需要使用NavController
而不是findFragmentById()
查找findNavController()
:
onCreate()
这是因为val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
依赖于已经创建的片段视图,而使用findNavController(R.id.nav_host_fragment)
则不是这种情况(因为它在引擎盖下使用FragmentContainerView
来添加{ {1}}。
答案 1 :(得分:4)
替换此行:
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
使用
NavController navController = getNavController();
getNavController()
如下所示:
// workaround for https://issuetracker.google.com/issues/142847973
@NonNull
private NavController getNavController() {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
if (!(fragment instanceof NavHostFragment)) {
throw new IllegalStateException("Activity " + this
+ " does not have a NavHostFragment");
}
return ((NavHostFragment) fragment).getNavController();
}
答案 2 :(得分:2)
在已接受的答案之上,可以使用的一些捷径是:
supportFragmentManager.findFragmentById(R.id.navHostMain)?.findNavController()
致谢
答案 3 :(得分:2)
我通过扩展解决了我的问题:
fun FragmentActivity.findFragmentContainerNavController(@IdRes host: Int):NavController {
try {
val navHostFragment = supportFragmentManager.findFragmentById(host) as NavHostFragment
return navHostFragment.findNavController()
} catch (e: Exception) {
throw IllegalStateException("Activity $this does not have a NavController set on $host")
}
}
答案 4 :(得分:1)
在你的 build.gradle (Module: App) 中加入这一行
implementation "androidx.navigation:navigation-fragment-ktx:2.3.2"
并在活动中使用它
val navController = supportFragmentManager.findFragmentById(R.id.your_id_nav_host_fragment)
?.findNavController()
并在片段中
val navController = findNavController()
答案 5 :(得分:0)
@friederbluemle 的答案还有一种更简单的方法。 断言检查就足够了。
NavHostFragment navHostFragment
= (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
assert navHostFragment != null : "navHostFragment not found";
NavController navController = navHostFragment.getNavController();
答案 6 :(得分:0)
这是简单的答案-
val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragmentContainerView)
作为 NavHostFragment
val navController = navHostFragment.navControllermenus.setupWithNavController(navController)