当我试图从一个片段导航到另一个片段时,我遇到了新的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。
任何帮助都将不胜感激。
当前回答
在我的情况下,我有多个导航图文件,我试图从一个导航图位置移动到另一个导航图的目的地。
为此,我们必须将第二个导航图像这样包含在第一个导航图中
<include app:graph="@navigation/included_graph" />
并将此添加到你的行动中:
<action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" />
其中second_graph为:
<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"
android:id="@+id/second_graph"
app:startDestination="@id/includedStart">
在第二张图中。
更多信息请点击这里
其他回答
您可以在导航之前检查请求导航的Fragment是否仍然是当前目的地,从这个要点出发。
它基本上是在片段上设置一个标记,以便稍后进行查找。
/**
* Returns true if the navigation controller is still pointing at 'this' fragment, or false if it already navigated away.
*/
fun Fragment.mayNavigate(): Boolean {
val navController = findNavController()
val destinationIdInNavController = navController.currentDestination?.id
val destinationIdOfThisFragment = view?.getTag(R.id.tag_navigation_destination_id) ?: destinationIdInNavController
// check that the navigation graph is still in 'this' fragment, if not then the app already navigated:
if (destinationIdInNavController == destinationIdOfThisFragment) {
view?.setTag(R.id.tag_navigation_destination_id, destinationIdOfThisFragment)
return true
} else {
Log.d("FragmentExtensions", "May not navigate: current destination is not the current fragment.")
return false
}
}
R.id。Tag_navigation_destination_id只是一个id,必须添加到ids.xml中,以确保它是唯一的。<item name="tag_navigation_destination_id" type="id" />
更多关于bug和解决方案的信息,以及navigateSafe(…)扩展方法在“修复可怕的”…是未知的NavController”
在我的情况下,问题发生时,我重用了我的片段内的一个viewpager片段作为viewpager的子。 viewpager片段(父片段)被添加到Navigation xml中,但动作没有添加到viewpager父片段中。
nav.xml
//reused fragment
<fragment
android:id="@+id/navigation_to"
android:name="com.package.to_Fragment"
android:label="To Frag"
tools:layout="@layout/fragment_to" >
//issue got fixed when i added this action to the viewpager parent also
<action android:id="@+id/action_to_to_viewall"
app:destination="@+id/toViewAll"/>
</fragment>
....
// viewpager parent fragment
<fragment
android:id="@+id/toViewAll"
android:name="com.package.ViewAllFragment"
android:label="to_viewall_fragment"
tools:layout="@layout/fragment_view_all">
修正了添加动作到父viewpager片段的问题,如下所示:
nav.xml
//reused fragment
<fragment
android:id="@+id/navigation_to"
android:name="com.package.to_Fragment"
android:label="To Frag"
tools:layout="@layout/fragment_to" >
//issue got fixed when i added this action to the viewpager parent also
<action android:id="@+id/action_to_to_viewall"
app:destination="@+id/toViewAll"/>
</fragment>
....
// viewpager parent fragment
<fragment
android:id="@+id/toViewAll"
android:name="com.package.ViewAllFragment"
android:label="to_viewall_fragment"
tools:layout="@layout/fragment_view_all"/>
<action android:id="@+id/action_to_to_viewall"
app:destination="@+id/toViewAll"/>
</fragment>
通常当这种情况发生在我身上时,我遇到了Charles Madere所描述的问题:在同一个ui上触发了两个导航事件,一个改变了currentDestination,另一个失败是因为currentDestination被改变了。 如果双击或单击两个视图,就会发生这种情况,其中有一个点击侦听器调用findNavController.navigate。
所以要解决这个问题,你可以使用if-checks, try-catch,或者如果你感兴趣,有一个findSafeNavController(),它在导航之前为你做这个检查。它还有一个检查,以确保您不会忘记这个问题。
GitHub
详细说明问题的文章
在我的情况下,我有多个导航图文件,我试图从一个导航图位置移动到另一个导航图的目的地。
为此,我们必须将第二个导航图像这样包含在第一个导航图中
<include app:graph="@navigation/included_graph" />
并将此添加到你的行动中:
<action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" />
其中second_graph为:
<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"
android:id="@+id/second_graph"
app:startDestination="@id/includedStart">
在第二张图中。
更多信息请点击这里
我通过检查当前目标中是否存在下一个操作来解决这个问题
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个不同的按钮