使用findNavController的FragmentContainerView

时间:2019-12-10 20:38:57

标签: android android-fragments android-navigation

我正在将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)
}

7 个答案:

答案 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)