Android 如何在导航体系结构组件中实现条件导航
在新的导航架构组件中,如何实现条件导航Android 如何在导航体系结构组件中实现条件导航,android,android-architecture-components,android-architecture-navigation,Android,Android Architecture Components,Android Architecture Navigation,在新的导航架构组件中,如何实现条件导航 目前,我有一个带有LoginFragment和HomeFragment的活动。基于某个login_标志,我曾经调用MainActivity中的任一片段。因为LoginFragment只被调用一次,所以我将startDestination设置为HomeFragment,导航加载这个HomeFragment。在导航加载HomeFragment之前,是否有办法检查login_标志。您可以在活动中添加导航侦听器,然后根据您的条件导航到LoginFragment,如
目前,我有一个带有LoginFragment和HomeFragment的活动。基于某个login_标志,我曾经调用MainActivity中的任一片段。因为LoginFragment只被调用一次,所以我将startDestination设置为HomeFragment,导航加载这个HomeFragment。在导航加载HomeFragment之前,是否有办法检查login_标志。您可以在活动中添加导航侦听器,然后根据您的条件导航到LoginFragment,如下所示:
findNavController(nav_host_fragment).addOnNavigatedListener { controller, destination ->
when(destination.id) {
R.id.HomeFragment-> {
if(someCondition) {
//Navigate to LoginFragment
}
}
}
<action
android:id="@+id/next_action"
app:popUpTo="@id/home_dest">
</action>
我是这样处理的:
<action
android:id="@+id/action_global_loginFragment"
app:destination="@id/loginFragment"
app:launchSingleTop="false"
app:popUpTo="@+id/nav_graph"
app:popUpToInclusive="true" />
我想补充一点,这方面有一个新的解决办法 在所有必需的片段中,定义“下一个动作”(ID显然不必是唯一的),如下所示:
findNavController(nav_host_fragment).addOnNavigatedListener { controller, destination ->
when(destination.id) {
R.id.HomeFragment-> {
if(someCondition) {
//Navigate to LoginFragment
}
}
}
<action
android:id="@+id/next_action"
app:popUpTo="@id/home_dest">
</action>
然后,您可以有条件地在代码中设置onClickListeners:
view.findViewById<Button>(R.id.navigate_action_button)?.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.next_action, null)
)
view.findViewById(R.id.navigate\u action\u按钮)?.setOnClickListener(
Navigation.createNavigateOnClickListener(R.id.next_action,null)
)
这种方法有一个问题。如果在应用程序处于后台时调用NavController.navigate(R.id.destinationId)
,您将得到一个错误:java.lang.IllegalStateException:在onSaveInstanceState之后无法执行此操作。这是导航体系结构组件中的错误吗?如果应用程序处于后台,为什么要调用navigate?例如,我在设备上运行应用程序,但由于超时(或其他原因)被锁定。然后我在Android Studio中单击运行应用程序。Android Studio启动了一个应用程序,然后出现了此异常,导致应用程序崩溃。你也可能陷入无休止的循环。例如,如果您的条件是loggedIn=false->则导航到登录片段。controller.navigation(…)将在导航到目标之前再次触发addOnNavigatedListener。它会进行必要的转换,但我的登录屏幕在操作栏中仍有返回箭头。你知道怎么摆脱它吗?@AleksN。是的,您需要定义多个“主”目的地,以便导航组件理解没有什么可返回的。将登录屏幕添加到目标集。请参阅。当使用此方法从全局片段导航回主片段时,我的UI卡住了。你能帮帮我吗?@MustufaAnsari你是如何返回的?登录后重定向的最佳方法是弹出LoginFragment,如下所示navController.popBackStack()
。还可以尝试双重检查/调试您的条件逻辑,并尝试使用popUpTo
和popuptinclusive
。由于我回答了这个问题,Jetpack有了很大的发展,尽管这个答案仍然相关,但代码可能需要用当前的最佳实践进行更新。例如,现在应该使用safeargs和Direction类。