当我试图从一个片段导航到另一个片段时,我遇到了新的Android导航架构组件的问题,我得到了这个奇怪的错误:
java.lang.IllegalArgumentException: navigation destination XXX
is unknown to this NavController
其他导航都很好,除了这个。
我使用Fragment的findNavController()函数来访问NavController。
任何帮助都将不胜感激。
当我试图从一个片段导航到另一个片段时,我遇到了新的Android导航架构组件的问题,我得到了这个奇怪的错误:
java.lang.IllegalArgumentException: navigation destination XXX
is unknown to this NavController
其他导航都很好,除了这个。
我使用Fragment的findNavController()函数来访问NavController。
任何帮助都将不胜感激。
当前回答
我写了这个扩展
fun Fragment.navigateAction(action: NavDirections) {
val navController = this.findNavController()
if (navController.currentDestination?.getAction(action.actionId) == null) {
return
} else {
navController.navigate(action)
}
}
其他回答
在我的情况下,我通过验证所有导航操作都正确地管理到各自的图形中,并更新了设备后退按钮的代码来解决这个问题,如下所示:
onBackPressedDispatcher.addCallback(this /* lifecycle owner */, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// Back is pressed... Finishing the activity
if (navHostFragment.childFragmentManager.backStackEntryCount == 0) {
// First fragment is open, backstack is empty
finish()
} else {
navHostFragment.navController.popBackStack()
}
}
})
更新的@Alex坚果解决方案
如果没有特定片段的操作,并希望导航到片段
fun NavController.navigateSafe(
@IdRes actionId: Int, @IdRes fragmentId: Int, args: Bundle? = null,
navOptions: NavOptions? = null, navExtras: Navigator.Extras? = null)
{
if (actionId != 0) {
val action = currentDestination?.getAction(actionId) ?: graph.getAction(actionId)
if (action != null && currentDestination?.id != action.destinationId) {
navigate(actionId, args, navOptions, navExtras)
}
} else if (fragmentId != 0 && fragmentId != currentDestination?.id)
navigate(fragmentId, args, navOptions, navExtras)
}
我写了这个扩展
fun Fragment.navigateAction(action: NavDirections) {
val navController = this.findNavController()
if (navController.currentDestination?.getAction(action.actionId) == null) {
return
} else {
navController.navigate(action)
}
}
在调用navigate之前检查currentDestination可能会有帮助。
例如,如果您在导航图fragmentA和fragmentB上有两个片段目的地,并且从fragmentA到fragmentB只有一个动作。当你已经在fragmentB上时,调用navigate(R.id.action_fragmentA_to_fragmentB)将导致IllegalArgumentException。因此,在导航之前,你应该总是检查currentDestination。
if (navController.currentDestination?.id == R.id.fragmentA) {
navController.navigate(R.id.action_fragmentA_to_fragmentB)
}
一个荒谬但非常强大的方法是: 简单地称之为:
view?.findNavController()?.navigateSafe(action)
只需创建这个扩展:
fun NavController.navigateSafe(
navDirections: NavDirections? = null
) {
try {
navDirections?.let {
this.navigate(navDirections)
}
}
catch (e:Exception)
{
e.printStackTrace()
}
}