Android 使用findNavController的FragmentContainerView
我正在使用带底部导航的Android导航组件,lint给出了一个关于用Android 使用findNavController的FragmentContainerView,android,android-fragments,android-navigation,Android,Android Fragments,Android Navigation,我正在使用带底部导航的Android导航组件,lint给出了一个关于用FragmentContainerView替换标记的警告,但当我替换时,findNavController不起作用,它给了我一个关于它没有设置NavController的错误 碎片 <androidx.fragment.app.FragmentContainerView android:id="@+id/nav_host_fragment" androi
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" />
根据,使用FragmentContainerView
时,需要使用findFragmentById()
查找NavController
,而不是在onCreate()中使用findNavController()
:
这是因为findNavController(R.id.nav_host_fragment)
依赖于已创建的片段视图,而使用FragmentContainerView
时,情况并非如此(因为它在引擎盖下使用FragmentTransaction
添加NavHostFragment
)。在已接受答案的顶部,可以使用的一个小捷径是:
supportFragmentManager.findFragmentById(R.id.navHostMain)?.findNavController()
关于替换此行:
NavController-NavController=Navigation.findNavController(这个R.id.nav_主机_片段);
与
NavController-NavController=getNavController();
其中getNavController()
如下所示:
//的解决方法https://issuetracker.google.com/issues/142847973
@非空
专用导航控制器getNavController(){
Fragment Fragment=getSupportFragmentManager().findFragmentById(R.id.nav_host_Fragment);
如果(!(NavHostFragment的片段实例)){
抛出新的非法状态异常(“活动”+此
+“没有NavHostFragment”);
}
返回((NavHostFragment)片段).getNavController();
}
有一种更简单的方法来回答@friederbluemle的问题。
断言检查就足够了
NavHostFragment navHostFragment
= (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
assert navHostFragment != null : "navHostFragment not found";
NavController navController = navHostFragment.getNavController();
将build.gradle(模块: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()
我通过扩展解决了我的问题:
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")
}
}
将FragmentContainerView
替换为fragment
我不想使用fragment
,如果我替换会有一个警告是的,在onCreate()
之外将创建片段的视图,因此调用findNavController()
这个答案在fragment.onCreate()内不起作用
。表示在onCreate()之前,NavController不可用。
。如果您在片段中,您将不会在此处使用任何东西,您将使用NavHostFragment.findNavController(此)
/findNavController()
@AdamHurwitz-是,NavigationAdvancedSample
使用完全独立的NavHostFragment
实例来支持多个后台堆栈,具体如下:;它使用了与任何文档完全不同的样式和功能。@Chuck-这不是一个“魔术变量”-Kotlin代码就是这样引用FragmentActivity
的getSupportFragmentManager()
API的。对我来说,这是最好的解决方案
val navController = findNavController()
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")
}
}