从带有 Jetpack 导航结果的 BottomSheetFragment 导航,出现崩溃“无法从当前目的地找到操作”
Posted
技术标签:
【中文标题】从带有 Jetpack 导航结果的 BottomSheetFragment 导航,出现崩溃“无法从当前目的地找到操作”【英文标题】:Navigating from BottomSheetFragment with Jetpack Navigation results with crash 'Action can not be found from current destination' 【发布时间】:2021-10-15 14:20:51 【问题描述】:这个案例可能是一个独特的案例,因为我确实有一些复杂的导航逻辑,并且我正在使用扩展功能(我将在下面分享)。
想象有一个 Fragment(A) 打开一个 BottomSheetFragment(B) BottomSheetFragment(B) 里面有一个按钮。 点击按钮会关闭 BottomSheetFragment(B) 并导航到新的 Fragment(C)。为了处理这种情况,我使用了 2 个扩展函数:
fun <T> Fragment.setNavigationResult(key: String, result: T)
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)
fun <T> Fragment.getNavigationResult(key: String) = findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T>(key)
在BottomSheetFragment(B)中实现setNavigationResult
loginButton.setOnClickListener
dismiss()
setNavigationResult(EVENT_CUSTOMER_SIGNUP_LOGIN, Event(true))
在 Fragment(A) 中实现getNavigationResult
getNavigationResult<Event<Boolean>>(EVENT_CUSTOMER_SIGNUP_LOGIN)?.observe(viewLifecycleOwner) event ->
event.value?.let
findNavController().navigate(R.id.openCustomerLogin)
应用程序崩溃并出现以下错误:
java.lang.IllegalArgumentException: Navigation action/destination openFragmentC cannot be found from the current destination Destination(FragmentB)
这里我不明白的是,即使我之前打电话给dismiss
,当前目的地仍然是BottomSheetFragment(B)
。
当我在导航到 FragmentC 之前添加延迟时,应用程序不会崩溃。
lifecycleScope.launch
delay(250)
findNavController().navigate(R.id.openCustomerLogin)
我不喜欢delay
的解决方案,因为它不实用,而且在新的实现中很容易被遗忘。
抱歉,这篇文章很长,如果您能分享您对此的想法并为我提供帮助,我将不胜感激。
【问题讨论】:
【参考方案1】:我已经实现如下
点击按钮时假设底部表格的代码如下
private fun closeBottomSheet()
findNavController().previousBackStackEntry?.savedStateHandle?.set("refresh", true)
findNavController().navigateUp()
片段A的以下代码
val observer = LifecycleEventObserver _, event ->
if (event == Lifecycle.Event.ON_RESUME
&& navBackStackEntry.savedStateHandle.contains("refresh")
)
val result = navBackStackEntry.savedStateHandle.get<Boolean>("refresh")
if (result!!)
result.run
// whatever you do , go from fragment A to Fragment C
navBackStackEntry.savedStateHandle.remove<Boolean>("refresh")
并检查您是否在 navigation.xml 中的片段 A 中定义了操作
【讨论】:
嗨 gaurav gupta,我尝试使用 findNavController().navigateUp() 而不是解雇。它仍然会立即崩溃(250)。片段 A 具有导航到片段 C 的定义,但片段 B 没有。 如果结果为空,你的应用程序会在这种情况下崩溃,我不会使用这样的代码。你应该改为result?.run ...
在 null 或 not null 的情况下,你编写这样的代码 result?.let result -> // 不管你做什么 以上是关于从带有 Jetpack 导航结果的 BottomSheetFragment 导航,出现崩溃“无法从当前目的地找到操作”的主要内容,如果未能解决你的问题,请参考以下文章
带有片段和 Jetpack 导航的 Viewpager2:恢复片段而不是重新创建它们
Android Jetpack导航,另一个主机片段内的主机片段
在 Scaffold Jetpack Compose 内的特定屏幕上隐藏顶部和底部导航器