FragmentContainerView 作为 NavHostFragment

95

看起来使用FragmentContainerView不能直接正常工作?

<androidx.fragment.app.FragmentContainerView
        class="androidx.navigation.fragment.NavHostFragment"
        android:id="@+id/fragment_nav_host"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_app" />

这是我使用的代码 fragment-ktx:1.2.0-rc01,但我一直收到以下错误:

Caused by: java.lang.IllegalStateException: Activity ...MainActivity@797467d does not have a NavController set on 2131296504

只是使用<fragment>就可以工作,据我所知,它只需要被FragmentContainerView替换。

我是否遗漏了什么或者有人能够将FragmentContainerView用作NavHostFragment

非常感谢!

5个回答

147

由于这个错误报告: https://issuetracker.google.com/issues/142847973

目前只有这种方式:

val navHostFragment = supportFragmentManager
    .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

(Java):

NavHostFragment navHostFragment =
    (NavHostFragment) getSupportFragmentManager()
        .findFragmentById(R.id.my_nav_host_fragment);
NavController navController = navHostFragment.getNavController();

13
只使用“fragment”而不必担心记住使用此解决方法,这样肯定更好,因为我们发现只有一些用户出现了崩溃,十分奇怪... - hmac
6
在所链接的问题中,讨论了为什么不应该使用 Fragment,https://issuetracker.google.com/issues/142847973#comment15:* 此处设置 Lint 检查正是因为在所有情况下都应该切换到 FragmentContainerView。* - Banana
很奇怪,我被迫使用<fragment>! - Junia Montana
1
我们需要对navController做什么,因为这个变量没有被使用。 - Tippu Fisal Sheriff

48

2020年8月更新

以下是官方Android文档推荐的解决方案。

Kotlin版本:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController

Java版本:

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
NavController navController = navHostFragment.getNavController();

我引用了文档:

使用FragmentContainerView创建NavHostFragment或者通过FragmentTransaction手动将NavHostFragment添加到活动中时,尝试在Activity的onCreate()方法中通过Navigation.findNavController(Activity, @IdRes int)检索NavController会失败。你应该直接从NavHostFragment中检索NavController。


Ove Stoerholt报告的错误不会被修复。你可以在这里看到“无法修复(不可行)”状态。


3
原始任务被标记为“无法解决(不可行)”,但是他们链接了另一个任务,因此他们可能计划修复问题:https://issuetracker.google.com/issues/143145612 - Sharp

10

我所做的是等待NavHostFragment填充其视图:

Kotlin:

我所做的是等待NavHostFragment填充其视图:
super.onCreate(savedInstanceState)

// Set up the form and list.
setContentView(R.layout.activity_xxx)

// Set up navigation - action bar and sidebar.
/// Let the navigation view check/uncheck the menu items.
nav_view.post { // wait for NavHostFragment to inflate
    val navController = findNavController()
    nav_view.setupWithNavController(navController)
    nav_view.setNavigationItemSelectedListener(this)
}

Java8(使用lambda):

navigationView.post(() -> { // wait for NavHostFragment to inflate
    navController = Navigation.findNavController(activity, R.id.nav_host_fragment);
    NavigationUI.setupWithNavController(navView, navController);
    navView.setNavigationItemSelectedListener(navItemSelectedListener);
});

我之前使用了<fragment>来避免一个bug。但是我又遇到了另一个未知的错误。所以我找到了@Pnemonic的晚回答,并尝试使用<FragmentContainerView>。问题已经解决,谢谢! - hata

3

使用Kotlin时我也遇到了相同的问题:

val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment

val navController = navHostFragment.navController

只需将其添加到

setupActionBarWithNavController(navController)


-8

使用android:name代替class。可以正常工作。

<androidx.fragment.app.FragmentContainerView
    android:name="androidx.navigation.fragment.NavHostFragment"
    ...

这个答案对我有用。正如文档所述: FragmentContainerView也可以通过使用android:name属性来添加Fragment。 https://developer.android.com/reference/androidx/fragment/app/FragmentContainerView - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接