如何使用 JetpackNavigation 组件从 BottomSheetDialogFragment 导航到另一个 Fragment

Posted

技术标签:

【中文标题】如何使用 JetpackNavigation 组件从 BottomSheetDialogFragment 导航到另一个 Fragment【英文标题】:How to navigate from BottomSheetDialogFragment to another Fragment using JetpackNavigation component 【发布时间】:2021-11-08 21:59:49 【问题描述】:

如果我尝试从底部工作表对话框片段导航到另一个片段,我的应用程序会崩溃。

我现在正在底部工作表对话框片段中执行此操作:

someButton.setOnClickListener  view ->  
   val action = DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment()
   view?.findNavController()?.navigate(action)

崩溃日志:

java.lang.IllegalStateException: View androidx.appcompat.widget.AppCompatButtonc44315f VFED..C.. ...P.... 44,1189-1036,1321 #7f0a00ff app:id/fragment_book_details_btn_edit does not have a NavController set
        at androidx.navigation.Navigation.findNavController(Navigation.java:84)
        at androidx.navigation.ViewKt.findNavController(View.kt:28)
        at com.bose.bosushree.view.book_details.BookDetailsFragment.setClickListeners$lambda-4$lambda-3(BookDetailsFragment.kt:75)
        at com.bose.bosushree.view.book_details.BookDetailsFragment.lambda$OwDld1VFgq8jsjr6EbpPx5MD4aU(Unknown Source:0)
        at com.bose.bosushree.view.book_details.-$$Lambda$BookDetailsFragment$OwDld1VFgq8jsjr6EbpPx5MD4aU.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:6256)
        at android.view.View$PerformClick.run(View.java:24701)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

【问题讨论】:

【参考方案1】:

因此,对话框片段在不同的窗口中工作,并且不在我们定义的 navController 的相同视图层次结构下。

这种情况下,我们需要从navHostFragment中找到我们的navController,然后进行导航:

someButton.setOnClickListener  view ->
                val action =
                    DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment()
                val navHostFragment =
                    requireActivity().supportFragmentManager
                        .findFragmentById(R.id.nav_host_fragment_container) as NavHostFragment
                navHostFragment.navController.navigate(action)
            

【讨论】:

【参考方案2】:

根据Navigate to a Destination guide,您可以使用findNavController() extension on Fragment 获取NavController。这适用于任何类型的片段,包括BottomSheetDialogFragment

someButton.setOnClickListener  view ->  
   val action = DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment()
   findNavController().navigate(action)

【讨论】:

我最初尝试过,但对我不起作用。 “对我不起作用”是什么意思?您正在通过<dialog> 标记和调用navigate() 将底部工作表添加到导航图中,对吧? 您的解决方案有效。为错误的方向道歉。我在视图上做错了什么。但我试过了,它奏效了。感谢您提供此解决方案。但是哪个更好用?我的解决方案需要一些额外的代码行 在片段中,您应该始终使用 Fragment.findNavController() 扩展名。这就是它存在的原因。

以上是关于如何使用 JetpackNavigation 组件从 BottomSheetDialogFragment 导航到另一个 Fragment的主要内容,如果未能解决你的问题,请参考以下文章

来自 JetpackNavigation 库中通知的隐式深层链接

未解决的参考:使用自定义 Parcelable 参数时:Jetpack Navigation

导航到 Jetpack Navigation 中的另一个 Fragment 后将 DialogFragment 保留在 backstack 中

android jetpack 导航仪器测试在返回导航上失败

带有 Jetpack Navigation 的 BottomNavigationView 未正确显示活动菜单指示器

说到Jetpack路由组件熟悉的只有ARouter框架?今天带你深入理解功能强大的Navigation架构