导航组件:在片段内使用 NavHostFragment

5
我有一个带有导航组件和BottomNavigationView的选项卡UI。 我的用例包含其中一个选项卡片段具有自己的BottomNavigationView
我认为嵌套导航图对我不起作用,因为我需要有一个内部的NavHostFragment和第二个BottomNavigationView
所以我在这个我希望托管内部导航图的片段中。它包含一个类似以下的片段。
<androidx.fragment.app.FragmentContainerView
        android:id="@+id/inner_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"

我需要一种方法来获取上述片段的导航控制器。
通常,在活动中,您会使用您为片段提供的ID,从supportFragmentManager调用findFragmentById。
val navHostFragment = supportFragmentManager.findFragmentById(R.id.outer_nav_host) as NavHostFragment

所以我尝试在我的内部片段中从活动对象调用它

requireActivity().supportFragmentManager.findFragmentById(R.id.inner_host_fragment)

但是findFragmentById返回null。


请注意,您应该始终使用FragmentContainerView,而特别不要使用已在Fragment 1.2.0中弃用的<fragment>标签。 - ianhanniballake
@ianhanniballake 感谢你的提醒。我已经更改为 FragmentContainerView。然而对于手头的情况并没有太大帮助。 - Vahid
1
没错,这就是为什么它是一条注释,而不是一个答案 :) - ianhanniballake
你能在 GitHub 上分享示例代码吗? - WISHY
1个回答

9
尝试从supportFragmentManager获取NavHostFragment,然后获取其上的navController。
val navHostFragment =
        requireActivity().supportFragmentManager.primaryNavigationFragment as NavHostFragment
val navController = navHostFragment.navController

感谢 @ianhanniballake 的建议,由于您当前的片段是另一个片段的子片段,您需要使用 childFragmentManager
因此,请尝试改为使用以下方法:
val navHostFragment =
    childFragmentManager.primaryNavigationFragment as NavHostFragment
val navController = navHostFragment.navController

更新:

抛出此 java.lang.NullPointerException: null cannot be cast to non-null type androidx.navigation.fragment.NavHostFragment

因此,根据评论的解决方案:

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

nav_host_fragment 替换为内部 NavHostFragment 的ID。


2
通过<fragment>标签来填充一个碎片意味着它是childFragmentManager的一部分,而不是Activity的FragmentManager的一部分,因此到sportFragmentManager的访问绝不是正确的方法。 - ianhanniballake
第一行抛出了以下异常: java.lang.NullPointerException: null 无法转换为非空类型 androidx.navigation.fragment.NavHostFragment。 - Vahid
1
@Vahid 很抱歉听到这个问题.. 你可以尝试使用以下代码 val navHostFragment = childFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment,将其中的 nav_host_fragment 替换为内部 navHostFragment 的 id。 - Zain
2
@Zain 谢谢你!我试了一下,它真的起作用了! - Vahid

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