首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NavController.OnDestinationChangedListener传递了与触发的导航操作ID不匹配的destination.id

NavController.OnDestinationChangedListener传递了与触发的导航操作ID不匹配的destination.id
EN

Stack Overflow用户
提问于 2020-03-14 18:18:00
回答 3查看 5.7K关注 0票数 16

在我的Android项目中,我有一个非常简单的导航图,包括两个片段: Master和Detail:

代码语言:javascript
运行
复制
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   app:startDestination="@id/wordsListFragment">

    <fragment
        android:id="@+id/wordsListFragment"
        android:name="com.***.presentation.view.WordsListFragment"
        android:label="List"
        tools:layout="@layout/words_list_fragment">
        <action
            android:id="@+id/action_wordsListFragment_to_wordDetailsFragment"
            app:destination="@id/wordDetailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/wordDetailsFragment"
        android:name="com.***.presentation.view.WordDetailsFragment"
        android:label="Details"
        tools:layout="@layout/word_details_fragment" />
</navigation>

导航本身在两个方向上都工作得很好,包括“后退”行为。在该项目中,我只有一个实现OnDestinationChangedListener的活动。所有这些都来自谷歌的以下文档:NavController Updating UI

当用户单击列表项时(在主片段上),我调用以下方法:

代码语言:javascript
运行
复制
findNavController().navigate(R.id.action_wordsListFragment_to_wordDetailsFragment, null)

然后,在父活动中,我有以下实现:

代码语言:javascript
运行
复制
private fun setupNavController() {
    navigationController = findNavController(R.id.nav_mainhost_fragment_container)
    navigationController.addOnDestinationChangedListener(mainDestinationChangedListener)
    appBarConfiguration = AppBarConfiguration(navigationController.graph)
    setupActionBarWithNavController(navigationController, appBarConfiguration)
}

这就是listener对象:

代码语言:javascript
运行
复制
private val mainDestinationChangedListener = 
NavController.OnDestinationChangedListener { controller, destination, arguments ->        

if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment) {
        actionBar?.hide()
    } else {
        actionBar?.show()
    }
}

但是destination.idR.id.action_wordsListFragment_to_wordDetailsFragment不匹配

我试图清理项目,清理IDE缓存和gradle缓存,但生成的标识符仍然不匹配。我还尝试通过安全参数使用导航:

代码语言:javascript
运行
复制
val action = WordsListFragmentDirections.actionWordsListFragmentToWordDetailsFragment()
findNavController().navigate(action)

但给定侦听器中的结果总是相同的(即不匹配)。

来自调试的一些值:

代码语言:javascript
运行
复制
findNavController().navigate(1000021) //R.id.action_wordsListFragment_to_wordDetailsFragment

但是栈上的下一个调用有另一个值:

还匹配传递给OnDestinationChangedListenerdestination.id值的是什么

代码语言:javascript
运行
复制
destination.id //2131231018

你方的任何提示都非常受欢迎。我只想识别目标或操作ID,并相应地调整ToolBar。

EN

回答 3

Stack Overflow用户

发布于 2020-03-14 19:49:49

您正在将fragmentIdactionId进行比较,因此它始终为假

这里是if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment)

As destination.id is fragmentIdR.id.action_wordsListFragment_to_wordDetailsFragment is actionId

要使其工作,您应该比较两个片段ids,如下所示

代码语言:javascript
运行
复制
if (destination.id == R.id.wordDetailsFragment)

*编辑

首先你应该找到你的navControler,然后监听它的目的地变化。

代码语言:javascript
运行
复制
val navController = findNavController(this,R.id.nav_host_fragment)// this maybe change
navController.addOnDestinationChangedListener { controller, destination, arguments ->
   if(destination.id == R.id.wordDetailsFragment) {
       actionBar?.hide()
   } else {
       actionBar?.show()
   }
}
票数 9
EN

Stack Overflow用户

发布于 2020-10-05 23:35:58

问题出在Android studio调试器上。如果我打印logcat中的值或将其赋给一个变量,则该值为2XXXXXXXXX,但如果我使用调试器进行计算,则该值为1XXXXXX。

我已经检查了APK中的动作id(R.id.xxxx)十六进制代码。当我将十六进制代码转换为整数时,它给出了一个2XXXXXXXXX中的值,该值等于在logcat中打印的值

票数 2
EN

Stack Overflow用户

发布于 2020-07-28 01:22:53

上述解决方案不起作用,您可以匹配目标片段的完全限定类名,而不是匹配目标片段的id,您的代码将变为

代码语言:javascript
运行
复制
navController.addOnDestinationChangedListener{ nc: NavController, nd: NavDestination, args: Bundle? ->

            val destinationClassName = (nc.currentDestination as FragmentNavigator.Destination).className

            when(destinationClassName) {

                "com.*domainName.*PackageName.*className" -> {
                    "Do you thing here"
                }

                else -> {
                    "Cater for the else block here"
                }
            }
        }
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60681700

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档