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>
我是这样处理的:

  • 将HomeFragment设置为
  • 为LoginFragment创建一个

    <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类。