当我试图从一个片段导航到另一个片段时,我遇到了新的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。
任何帮助都将不胜感激。
当前回答
您可以在导航控制器的当前目标中检查请求的操作。
更新 为安全导航增加了全局操作的使用。
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)
}
}
其他回答
通常当这种情况发生在我身上时,我遇到了Charles Madere所描述的问题:在同一个ui上触发了两个导航事件,一个改变了currentDestination,另一个失败是因为currentDestination被改变了。 如果双击或单击两个视图,就会发生这种情况,其中有一个点击侦听器调用findNavController.navigate。
所以要解决这个问题,你可以使用if-checks, try-catch,或者如果你感兴趣,有一个findSafeNavController(),它在导航之前为你做这个检查。它还有一个检查,以确保您不会忘记这个问题。
GitHub
详细说明问题的文章
我解决了同样的问题,把检查之前导航,而不是样板代码点击即时控制
if (findNavController().currentDestination?.id == R.id.currentFragment) {
findNavController().navigate(R.id.action_current_next)}
/* Here R.id.currentFragment is the id of current fragment in navigation graph */
根据这个答案
https://stackoverflow.com/a/56168225/7055259
在我的情况下,问题发生时,我重用了我的片段内的一个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>
似乎混合fragmentManager控件的backstack和Navigation Architecture控件的backstack也会导致这个问题。
例如,最初的CameraX基本示例使用fragmentManager后台导航,如下所示,它似乎没有正确地与导航交互:
// Handle back button press
view.findViewById<ImageButton>(R.id.back_button).setOnClickListener {
fragmentManager?.popBackStack()
}
如果你在从主片段(在本例中是相机片段)移动之前记录这个版本的“当前目的地”,然后当你返回主片段时再次记录它,你可以从日志中的id中看到id是不相同的。据猜测,导航在移动到片段时更新了它,而fragmntManager在移动回来时没有再次更新它。日志显示:
修改前:D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元 After: D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@9807d8f美元
更新版的CameraX基本示例使用导航返回如下:
// Handle back button press
view.findViewById<ImageButton>(R.id.back_button).setOnClickListener {
Navigation.findNavController(requireActivity(), R.id.fragment_container).navigateUp()
}
这可以正常工作,当返回到主片段时,日志显示相同的id。
修改前:D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元 After: D/CameraXBasic: currentDest?: androidx.navigation.fragment.FragmentNavigator Destination@b713195美元
我怀疑这个故事的寓意,至少在这个时候,是要非常小心地混合导航和fragmentManager导航。
这发生在我身上,我的问题是我在标签项片段上单击FAB。我试图从一个标签项片段导航到另一个片段。
但是根据Ian Lake的回答,我们必须使用tablayout和viewpager,没有导航组件支持。因此,没有从包含片段的标签布局到标签项片段的导航路径。
ex:
containing fragment -> tab layout fragment -> tab item fragment -> another fragment
解决方案是创建一个从包含片段的标签布局到预期片段的路径 例如:path: container fragment ->另一个片段
劣势:
导航图不再准确地代表用户流。