当我试图从一个片段导航到另一个片段时,我遇到了新的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。
任何帮助都将不胜感激。
当前回答
我通过检查当前目标中是否存在下一个操作来解决这个问题
public static void launchFragment(BaseFragment fragment, int action) {
if (fragment != null && NavHostFragment.findNavController(fragment).getCurrentDestination().getAction(action) != null) {
NavHostFragment.findNavController(fragment).navigate(action);
}
}
public static void launchFragment(BaseFragment fragment, NavDirections directions) {
if (fragment != null && NavHostFragment.findNavController(fragment).getCurrentDestination().getAction(directions.getActionId()) != null) {
NavHostFragment.findNavController(fragment).navigate(directions);
}
}
这解决了一个问题,如果用户快速点击2个不同的按钮
其他回答
如果你有的话,这种情况也会发生 一个片段a和片段B的ViewPager 你试着从B导航到C
因为在ViewPager中片段不是a的目的地,所以你的图形不会知道你在B上。
一种解决方案是在B中使用A方向导航到C
更新到@AlexNuts回答以支持导航到嵌套图。当一个动作使用一个嵌套图作为目的地时,如下所示:
<action
android:id="@+id/action_foo"
android:destination="@id/nested_graph"/>
此操作的目的ID不能与当前目的进行比较,因为当前目的不能是图形。必须解析嵌套图的起始目的地。
fun NavController.navigateSafe(directions: NavDirections) {
// Get action by ID. If action doesn't exist on current node, return.
val action = (currentDestination ?: graph).getAction(directions.actionId) ?: return
var destId = action.destinationId
val dest = graph.findNode(destId)
if (dest is NavGraph) {
// Action destination is a nested graph, which isn't a real destination.
// The real destination is the start destination of that graph so resolve it.
destId = dest.startDestination
}
if (currentDestination?.id != destId) {
navigate(directions)
}
}
然而,这将防止导航到同一目的地两次,这是有时需要的。为了允许这一点,你可以添加一个检查action.navOptions?. shouldlaunchsingletop(),并添加app:launchSingleTop="true"的动作,你不希望重复的目的地。
当我按了两次后退键时,我想到了这个问题。首先,我拦截KeyListener并覆盖KeyEvent.KEYCODE_BACK。我在名为OnResume的函数中添加了下面的代码,然后解决了这个问题/问题。
override fun onResume() {
super.onResume()
view?.isFocusableInTouchMode = true
view?.requestFocus()
view?.setOnKeyListener { v, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
activity!!.finish()
true
}
false
}
}
当我第二次遇到这种情况时,它的状态与第一次相同,我发现我可能会使用add函数。让我们来分析一下这些情况。
首先,FragmentA导航到FragmentB,然后FragmentB导航到FragmentA,然后按下返回按钮…崩溃出现了。 其次,FragmentA导航到FragmentB,然后FragmentB导航到FragmentC, FragmentC导航到FragmentA,然后按下返回按钮…崩溃出现了。
所以我认为当按下返回按钮时,FragmentA会回到FragmentB或FragmentC,这会导致登录混乱。最后,我发现名为popBackStack的函数可以用于返回,而不是导航。
NavHostFragment.findNavController(this@TeacherCloudResourcesFragment).
.popBackStack(
R.id.teacher_prepare_lesson_main_fragment,false
)
到目前为止,问题已经真正解决了。
如果你使用的是recyclerview,只需在你的点击上添加一个点击监听器冷却时间,并在你的recyclerview xml文件中使用android:splitMotionEvents="false"
在我的情况下,我通过验证所有导航操作都正确地管理到各自的图形中,并更新了设备后退按钮的代码来解决这个问题,如下所示:
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()
}
}
})