Android 使用findNavController的FragmentContainerView

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

我正在使用带底部导航的Android导航组件,lint给出了一个关于用
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")
    }
}