在我的Android项目中,我有一个非常简单的导航图,包括两个片段: Master和Detail:
<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
当用户单击列表项时(在主片段上),我调用以下方法:
findNavController().navigate(R.id.action_wordsListFragment_to_wordDetailsFragment, null)
然后,在父活动中,我有以下实现:
private fun setupNavController() {
navigationController = findNavController(R.id.nav_mainhost_fragment_container)
navigationController.addOnDestinationChangedListener(mainDestinationChangedListener)
appBarConfiguration = AppBarConfiguration(navigationController.graph)
setupActionBarWithNavController(navigationController, appBarConfiguration)
}
这就是listener对象:
private val mainDestinationChangedListener =
NavController.OnDestinationChangedListener { controller, destination, arguments ->
if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment) {
actionBar?.hide()
} else {
actionBar?.show()
}
}
但是destination.id
与R.id.action_wordsListFragment_to_wordDetailsFragment
不匹配
我试图清理项目,清理IDE缓存和gradle缓存,但生成的标识符仍然不匹配。我还尝试通过安全参数使用导航:
val action = WordsListFragmentDirections.actionWordsListFragmentToWordDetailsFragment()
findNavController().navigate(action)
但给定侦听器中的结果总是相同的(即不匹配)。
来自调试的一些值:
findNavController().navigate(1000021) //R.id.action_wordsListFragment_to_wordDetailsFragment
但是栈上的下一个调用有另一个值:
还匹配传递给OnDestinationChangedListener
的destination.id
值的是什么
destination.id //2131231018
你方的任何提示都非常受欢迎。我只想识别目标或操作ID,并相应地调整ToolBar。
发布于 2020-03-14 19:49:49
您正在将fragmentId与actionId进行比较,因此它始终为假
这里是if (destination.id == R.id.action_wordsListFragment_to_wordDetailsFragment)
As destination.id
is fragmentId和R.id.action_wordsListFragment_to_wordDetailsFragment
is actionId
要使其工作,您应该比较两个片段ids,如下所示
if (destination.id == R.id.wordDetailsFragment)
*编辑
首先你应该找到你的navControler,然后监听它的目的地变化。
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()
}
}
发布于 2020-10-05 23:35:58
问题出在Android studio调试器上。如果我打印logcat中的值或将其赋给一个变量,则该值为2XXXXXXXXX,但如果我使用调试器进行计算,则该值为1XXXXXX。
我已经检查了APK中的动作id(R.id.xxxx)十六进制代码。当我将十六进制代码转换为整数时,它给出了一个2XXXXXXXXX中的值,该值等于在logcat中打印的值
发布于 2020-07-28 01:22:53
上述解决方案不起作用,您可以匹配目标片段的完全限定类名,而不是匹配目标片段的id,您的代码将变为
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"
}
}
}
https://stackoverflow.com/questions/60681700
复制相似问题