在 NavController 中避免 Android 导航 IllegalArgumentException
Avoiding Android navigation IllegalArgumentException in NavController
我最近切换到 Android 导航,但遇到了很多情况(在代码的不同部分),我得到:
Fatal Exception: java.lang.IllegalArgumentException
navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController
在每种情况下,代码都是简单的调用,例如:
findNavController(this, R.id.navigation_host_fragment).navigate(R.id.action_aFragment_to_bFragment)
通常响应按钮按下。
不清楚为什么会抛出此错误。我目前的怀疑是 onClickListener 在某些设备上以某种方式被调用两次,导致导航被第二次调用(导致它当时处于错误状态)。这种怀疑的原因是,这似乎最常发生在导航调用之前可能有 "long" 运行 操作的情况下。不过,我无法在自己的设备上重新创建它。
关于如何避免此问题的想法(或者实际上,问题的实际根本原因是什么)?
我不想使用全局操作;我对向后台堆栈引入更多意想不到的状态持谨慎态度。而且我真的不想在每次进行导航调用时都尝试测试当前状态。
好吧,让我向你解释一下这个异常是通过的,因为我们正在从一个片段(目标)调用一个动作,它不是堆栈上的当前目标。
即
你正在调用一个动作
R.id.action_aFragment_to_bFragment
来自 fragmentA 但在 navController 中,当前目的地是 fragmentA 以外的地方。这就是为什么 navController 通过该异常:
navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController
您可以在导航前查看当前目的地。喜欢
Toast.makeText(context,view?.findNavController()?.currentDestination?.label,Toast.LENGTH_SHORT).show()
这会告诉你当前的目的地,我相信那会是其他目的地。
当我们替换动作以外的片段(例如通过不带导航的旧方法)或者我们在调用动作之前弹出该片段时,就会发生这种情况。
如果是这种情况,那么您必须使用 Global Action,因为他们不关心当前目的地是什么。
您可以在导航前使用以下代码检查当前目的地是否正确。这将确保调用仅从当前片段发生。通过同时单击两个视图(列表中的两个项目)可以重现此问题。
if (findNavController().currentDestination?.id == R.id.currentFragment) {
findNavController().navigate(R.id.action_current_next)
}
我最近切换到 Android 导航,但遇到了很多情况(在代码的不同部分),我得到:
Fatal Exception: java.lang.IllegalArgumentException
navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController
在每种情况下,代码都是简单的调用,例如:
findNavController(this, R.id.navigation_host_fragment).navigate(R.id.action_aFragment_to_bFragment)
通常响应按钮按下。
不清楚为什么会抛出此错误。我目前的怀疑是 onClickListener 在某些设备上以某种方式被调用两次,导致导航被第二次调用(导致它当时处于错误状态)。这种怀疑的原因是,这似乎最常发生在导航调用之前可能有 "long" 运行 操作的情况下。不过,我无法在自己的设备上重新创建它。
关于如何避免此问题的想法(或者实际上,问题的实际根本原因是什么)?
我不想使用全局操作;我对向后台堆栈引入更多意想不到的状态持谨慎态度。而且我真的不想在每次进行导航调用时都尝试测试当前状态。
好吧,让我向你解释一下这个异常是通过的,因为我们正在从一个片段(目标)调用一个动作,它不是堆栈上的当前目标。
即 你正在调用一个动作
R.id.action_aFragment_to_bFragment
来自 fragmentA 但在 navController 中,当前目的地是 fragmentA 以外的地方。这就是为什么 navController 通过该异常:
navigation destination com.xxx.yyy:id/action_aFragment_to_bFragment is unknown to this NavController
您可以在导航前查看当前目的地。喜欢
Toast.makeText(context,view?.findNavController()?.currentDestination?.label,Toast.LENGTH_SHORT).show()
这会告诉你当前的目的地,我相信那会是其他目的地。
当我们替换动作以外的片段(例如通过不带导航的旧方法)或者我们在调用动作之前弹出该片段时,就会发生这种情况。
如果是这种情况,那么您必须使用 Global Action,因为他们不关心当前目的地是什么。
您可以在导航前使用以下代码检查当前目的地是否正确。这将确保调用仅从当前片段发生。通过同时单击两个视图(列表中的两个项目)可以重现此问题。
if (findNavController().currentDestination?.id == R.id.currentFragment) {
findNavController().navigate(R.id.action_current_next)
}