当我试图从一个片段导航到另一个片段时,我遇到了新的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。
任何帮助都将不胜感激。
当前回答
造成这个问题的原因可能有很多。 在我的情况下,我正在使用MVVM模型,我正在观察布尔导航 当布尔值为true时->导航 否则什么都不要做 这工作得很好,但这里有一个错误
当从目标片段按下返回按钮时,我遇到了同样的问题。问题是布尔对象,因为我忘记将布尔值更改为false,这造成了混乱。我刚刚在viewModel中创建了一个函数,将其值更改为false,并在findNavController()之后调用它
其他回答
试试
创建以下扩展函数(或普通函数):
UPDATED(不带反射,可读性更强)
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.DialogFragmentNavigator
import androidx.navigation.fragment.FragmentNavigator
fun Fragment.safeNavigateFromNavController(directions: NavDirections) {
val navController = findNavController()
when (val destination = navController.currentDestination) {
is FragmentNavigator.Destination -> {
if (javaClass.name == destination.className) {
navController.navigate(directions)
}
}
is DialogFragmentNavigator.Destination -> {
if (javaClass.name == destination.className) {
navController.navigate(directions)
}
}
}
}
老了(沉思)
import androidx.fragment.app.Fragment
import androidx.navigation.NavController
import androidx.navigation.NavDirections
import androidx.navigation.fragment.FragmentNavigator
inline fun <reified T : Fragment> NavController.safeNavigate(directions: NavDirections) {
val destination = this.currentDestination as FragmentNavigator.Destination
if (T::class.java.name == destination.className) {
navigate(directions)
}
}
然后像这样使用你的片段:
val direction = FragmentOneDirections.actionFragmentOneToFragmentTwo()
// new usage
safeNavigateFromNavController(direction)
// old usage
// findNavController().safeNavigate<FragmentOne>(action)
我的问题是
我有一个片段(FragmentOne),它指向另外两个片段(FragmentTwo和FragmentThree)。在一些低级设备中,用户按下重定向到FragmentTwo的按钮,但在用户按下重定向到FragmentThree的按钮几毫秒后。结果是:
致命异常:java.lang.IllegalArgumentException导航 action/destination action_fragmentOne_to_fragmentTwo找不到 来自当前目的地 类= FragmentThree
我的答案是:
我检查当前目的地是否属于当前片段。如果为真,则执行导航操作。
就这些!
如果你点击太快,它会导致null和崩溃。
我们可以使用RxBinding库来帮助这一点。你可以在点击发生之前添加节流和持续时间。
RxView.clicks(view).throttleFirst(duration, TimeUnit.MILLISECONDS)
.subscribe(__ -> {
});
这些关于在Android上节流的文章可能会有所帮助。干杯!
答案在链接:https://stackoverflow.com/a/67614469/5151336
为导航器增加了安全导航的扩展功能。
正如在其他回答中提到的,此异常通常发生在用户
同时单击处理导航的多个视图 在处理导航的视图上多次单击。
使用计时器来禁用单击并不是处理此问题的合适方法。如果用户在计时器过期后还没有导航到目的地,应用程序无论如何都会崩溃,在许多情况下,导航不是执行的动作,快速点击是必要的。
在情况1中,android:splitMotionEvents=“false”在xml或setMotionEventSplittingEnabled(false)在源文件应该有帮助。将此属性设置为false将只允许一个视图进行单击。你可以在这里阅读
在情况2中,会有一些东西延迟导航过程,允许用户多次单击视图(API调用,动画等)。如果可能的话,应该解决根本问题,以便即时进行导航,不允许用户两次单击视图。如果延迟是不可避免的,就像在API调用的情况下,禁用视图或使其不可点击将是适当的解决方案。
将我的答案优雅地扔到处理两种情况(双击,同时点击两个按钮)的环中,但尽量不掩盖真正的错误。
我们可以使用navigateSafe()函数来检查我们试图导航到的目的地从当前目的地是否是无效的,但从前一个目的地是否是有效的。如果是这种情况,代码假设用户双击或同时点击两个按钮。
然而,这个解决方案并不完美,因为它可能会掩盖一些小众情况下的实际问题,即我们试图导航到恰好是父端的目的地。但据推测,这种情况不太可能发生。
代码:
fun NavController.navigateSafe(directions: NavDirections) {
val navigateWillError = currentDestination?.getAction(directions.actionId) == null
if (navigateWillError) {
if (previousBackStackEntry?.destination?.getAction(directions.actionId) != null) {
// This is probably some user tapping two different buttons or one button twice quickly
// Ignore...
return
}
// This seems like a programming error. Proceed and let navigate throw.
}
navigate(directions)
}