如何使用Jetpack Navigation从BottomSheetDialogFragment导航至其他Fragment并解决崩溃
问题原因
崩溃是因为BottomSheetDialogFragment的视图附着在独立的Dialog窗口上,不属于宿主导航组件管理的视图树,直接通过点击控件调用findNavController()无法检索到对应的NavController,所以抛出了IllegalStateException异常。
解决方法
以下是三种稳定可用的修复方案,可根据你的业务场景选择:
- 方案1:通过父Fragment获取导航控制器(适用BottomSheet由普通Fragment弹出的场景)
将点击事件中的导航逻辑修改为如下代码:
someButton.setOnClickListener { val action = DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment() requireParentFragment().findNavController().navigate(action) }
- 方案2:通过Activity获取导航控制器(适用导航图挂载在Activity层级的场景)
将代码中的导航宿主ID替换为你自己布局中NavHostFragment对应的ID即可:
someButton.setOnClickListener { val action = DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment() requireActivity().findNavController(R.id.你的导航宿主ID).navigate(action) }
- 方案3:提前缓存导航控制器(性能更优,避免重复检索)
在onViewCreated生命周期中提前拿到NavController存储,点击时直接调用:
private lateinit var navController: NavController override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 二选一获取导航控制器 navController = requireParentFragment().findNavController() // 或者 navController = requireActivity().findNavController(R.id.你的导航宿主ID) someButton.setOnClickListener { val action = DestinationFragmentDirections.actionCurrentFragmentToDestinationFragment() navController.navigate(action) } }
注意事项
不要尝试通过BottomSheet自身的任何视图(包括根视图、点击控件)调用findNavController(),这类视图均不属于导航组件的视图树,无法检索到NavController。
内容的提问来源于stack exchange,提问作者Ankush
相关产品推荐
相关产品推荐

