FragmentContainerView 使用 findNavController

Jim*_*bdi 44 android android-fragments android-navigation

我正在使用带有底部导航的 Android 导航组件,lint 给出了关于替换<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" />
Run Code Online (Sandbox Code Playgroud)

活动

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)
}
Run Code Online (Sandbox Code Playgroud)

ian*_*ake 108

根据这个问题,在使用时FragmentContainerView,您需要找到NavControllerusingfindFragmentById()而不是 using findNavController()when in onCreate()

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
Run Code Online (Sandbox Code Playgroud)

这是因为findNavController(R.id.nav_host_fragment)依赖于已经创建的 Fragment 的视图,这在使用时并非如此FragmentContainerView(因为它FragmentTransaction在幕后使用了来添加NavHostFragment)。

  • 如果你在 Fragment 中,你不会在这里使用任何东西,你会使用 `NavHostFragment.findNavController(this)` / `findNavController()`。 (3认同)
  • @Chuck - 这不是一个“魔法变量” - 这就是 Kotlin 代码引用 `FragmentActivity` 的 `getSupportFragmentManager()` API 的方式。 (2认同)

fri*_*mle 7

替换这一行:

NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
Run Code Online (Sandbox Code Playgroud)

NavController navController = getNavController();
Run Code Online (Sandbox Code Playgroud)

哪里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();
    }
Run Code Online (Sandbox Code Playgroud)