当前位置: 首页 > 知识库问答 >
问题:

IllegalArgumentException:导航目标xxx对此NavController未知

柳宾实
2023-03-14

当我尝试从一个片段导航到另一个片段时,我对新的Android导航架构组件有一个问题,我得到了一个奇怪的错误:

java.lang.IllegalArgumentException: navigation destination XXX
is unknown to this NavController

除此之外,其他导航都可以正常工作。

我使用片段的函数findNavController()访问导航控制器。

任何帮助将不胜感激。

共有3个答案

曾飞雨
2023-03-14

您可以在导航控制器的当前目的地检查请求的操作。

更新添加了安全导航全局操作的用法。

fun NavController.navigateSafe(
        @IdRes resId: Int,
        args: Bundle? = null,
        navOptions: NavOptions? = null,
        navExtras: Navigator.Extras? = null
) {
    val action = currentDestination?.getAction(resId) ?: graph.getAction(resId)
    if (action != null && currentDestination?.id != action.destinationId) {
        navigate(resId, args, navOptions, navExtras)
    }
}
袁鹤轩
2023-03-14

在调用navigate之前,请检查currentDestination。

例如,如果您在导航图上有两个碎片目的地,并且从碎片A到碎片B只有一个动作。调用navigate(R.id.action\u fragmentA\u to\u fragmentB)将导致当您已经在fragmentB上时出现IllegalArgumentException。因此,在导航之前,您应该始终检查当前目的地。

if (navController.currentDestination?.id == R.id.fragmentA) {
    navController.navigate(R.id.action_fragmentA_to_fragmentB)
}
杜志
2023-03-14

在我的例子中,如果用户非常快地点击同一个视图两次,就会发生这种崩溃。所以你需要实现某种逻辑来防止多次快速点击。。。这很烦人,但似乎是必要的。

你可以在这里阅读更多关于防止这种情况的内容:Android防止双击按钮

2019年3月19日编辑:只是为了进一步澄清,这种崩溃并不是通过“非常快速地单击同一个视图两次”就能完全重现的。或者,您可以使用两个手指同时单击两个(或多个)视图,其中每个视图都有自己的导航,它们会执行。当您有一个项目列表时,这特别容易做到。上述关于多次点击预防的信息将处理这种情况。

2020年4月16日编辑:为了防止你对阅读上面的堆栈溢出帖子不太感兴趣,我将包括我自己的(Kotlin)解决方案,我已经使用了很长时间了。

class OnSingleClickListener : View.OnClickListener {

    private val onClickListener: View.OnClickListener

    constructor(listener: View.OnClickListener) {
        onClickListener = listener
    }

    constructor(listener: (View) -> Unit) {
        onClickListener = View.OnClickListener { listener.invoke(it) }
    }

    override fun onClick(v: View) {
        val currentTimeMillis = System.currentTimeMillis()

        if (currentTimeMillis >= previousClickTimeMillis + DELAY_MILLIS) {
            previousClickTimeMillis = currentTimeMillis
            onClickListener.onClick(v)
        }
    }

    companion object {
        // Tweak this value as you see fit. In my personal testing this
        // seems to be good, but you may want to try on some different
        // devices and make sure you can't produce any crashes.
        private const val DELAY_MILLIS = 200L

        private var previousClickTimeMillis = 0L
    }

}
fun View.setOnSingleClickListener(l: View.OnClickListener) {
    setOnClickListener(OnSingleClickListener(l))
}

fun View.setOnSingleClickListener(l: (View) -> Unit) {
    setOnClickListener(OnSingleClickListener(l))
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    settingsButton.setOnSingleClickListener {
        // navigation call here
    }
}
 类似资料:
  • 当用户单击通知时,我需要导航到一个片段。 如果应用程序正在运行,这可以正常工作。但是,当我退出应用程序,然后单击通知时,它会崩溃,并显示以下错误消息: 我的导航代码: 如何实例化我的navController 我想这是因为我的导航控制器没有正确初始化?有什么想法可以解决这个问题/正确的方法是什么?

  • 我目前正在我的项目中使用Android导航架构。它有一个功能,可以通过快捷方式启动任何片段。目前我正在使用NavController在单击快捷方式时导航到所需的目的地。但是当我多次单击快捷方式时,每次都会创建一个新的片段实例。所以,我的问题是,有没有办法在使用NavController导航到一个片段时只接受一个片段实例?我谷歌了很多次,但一无所获。提前感谢。

  • 我试图将导航栏项目水平居中对齐,但它们向左对齐。 有人能帮忙吗? 这是一个桌面问题-只是要明确,我有这个问题在桌面级别。 这是我目前的代码: 演示:https://jsfiddle.net/cjoasysz/

  • 导航标签用于生成前台导航,相关的有三个标签navigation,navigationMenu,navigationFolder,三个必须联合使用 navigation标签 标签名 作用 包含属性 navigation 导航标签 nav-id,root,id,class 标签属性: | 标签属性名 | 含义 | | --- | --- | | nav-id |后台导航 id,非必须 | | root

  • 导航标签用于生成前台导航,相关的有三个标签navigation,navigationMenu,navigationFolder,三个必须联合使用 navigation标签 标签名 作用 包含属性 navigation 导航标签 nav-id,root,id,class 标签属性: | 标签属性名 | 含义 | | --- | --- | | nav-id |后台导航 id,非必须 | | root

  • 本功能是响应大家需求,后期加上的,其实本人在公司项目或者个人项目中是不太使用该功能的。以前那些传统后台框架往往会包含此功能,由于以前的后台项目大部分都是多页面的形式,所以标签栏导航功能还是具有一定意义的,大部分都是基于 iframe 的方式实现的。 但随着时代的发展,现在的后台项目几乎都是 spa(single page web application 单页面开发),再使用以前的方案来实现标签导航