Android导航组件-如何“ popBackStack”到不存在的目的地

问题描述

我的应用中的认路由为-Auth -> Main -> Chat。但是有时我需要使用另一条路由:Auth -> Details -> Chat。当我按后退按钮(在两种情况下)时,我都想导航到Main屏幕,但是在第二种情况下它不在后退堆栈中。我尝试创建Global-action并使用DetailsChat屏幕导航到popUpTo == Main

<action
    android:id="@+id/action_global_to_chat"
    app:destination="@id/navigation_chat"
    app:launchSingletop="true"
    app:popUpTo="@id/navigation_main_host" />

但是它不起作用,因为navigation_main_host不在后台。有什么办法可以做到这一点?

UPD::我尝试了另一种解决方案-我在Chat目标中以popup inclusive的行为创建了另一个动作:

    <action
        android:id="@+id/action_chat_to_main_host"
        app:destination="@id/navigation_main_host"
        app:popUpTo="@id/navigation_auth"
        app:popUpToInclusive="true" />

然后我尝试在ChatFragment中使用它:

private val backpressedCallback = object : OnBackpressedCallback(true) {
    override fun handleOnBackpressed() {
        if (activityController?.getNavController()?.prevIoUsBackStackEntry?.destination?.id == R.id.navigation_main_host) {
            activityController?.getNavController()?.popBackStack()
        } else {
            activityController?.getNavController()?.navigate(ChatDirections.actionChatToMainHost())
        }
    }
}

但是当我尝试时,我得到了这条路线:

Auth -> Details -> Chat

然后我开始按后退按钮:

Chat -> Main -> Chat -> Main -> Chat -> Main....在无限循环中。

backpressedCallbackonResume中已启用,在onPause中已禁用,以使其清晰可见。

解决方法

我有一个类似的用例。分享我的实施。希望它对您有用。

在MainActivity中:

// Navigation component global variables
private lateinit var navController: NavController
private lateinit var navGraph: NavGraph

// In onCreate()
// fragment_activitymain is a <fragment>
navController = findNavController(R.id.fragment_activitymain)
navGraph = navController.navInflater.inflate(R.navigation.navigation)

private fun setStartDestination(startDestination: Int) {
    navGraph.startDestination = startDestination
    navController.graph = navGraph
}

要调用方法setStartDestination():

setStartDestination(R.id.MainFragmentIdInNavigationGraph)

可以通过使用接口或将setStartDestination()livedata一起使用shared ViewModel或在您的活动中实现活动片段与活动通信的任何其他方式,从任何片段中调用活动中的方法Newdata = data.groupby(['Department','Sex'])[['Personal Identifier']].count().reset_index().rename(columns={'Personal Identifier':'TotalStaff'}) fig = px.bar(Newdata,x ='Department',y='TotalStaff',color='Sex',barmode='group',text='TotalStaff',title = 'Staff By Dept') fig.show() Newdata2 = data.groupby(['Post Type','Sex'])[['Personal Identifier']].count().reset_index().rename(columns={'Personal Identifier':'TotalStaff'}) fig2 = px.bar(Newdata2,x ='Post Type',title = 'Staff By Post Type') fig2.show() 应用程序。

要获得所需的流程,请在“聊天”中按回车,然后使用操作从“聊天”导航到“主要”,而不是从后退弹出目标。将“ Main”设置为开始目标会清除main下的目标。

流程的工作原理如下: 路线1: 身份验证->主菜单->聊天->使用操作导航到主菜单并将其设置为开始方法,以从后堆栈中清除“聊天”和“主菜单”。在Auth to Main操作中使用popUp时,“ Auth”将不会出现在后退堆栈中。

路线2: 身份验证->详细信息->聊天->使用操作导航到主菜单并将其设置为开始方法,以从后堆栈中清除“聊天”和“详细信息”。如果您在Auth to Details操作中使用popUp,则“ Auth”将不在后堆栈中,否则它将在后堆栈中,当我们更改起始目的地时,也会清除该内容。

,

有点hacky,但是您可以尝试:

private val backPressedCallback = object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {
        if (activityController?.getNavController()?.previousBackStackEntry?.destination?.id == R.id.navigation_main_host) {
            activityController?.getNavController()?.popBackStack()
        } else {
            activityController?.getNavController()?.popBackStack(R.id.navigation_auth,true)
            activityController?.getNavController()?.navigate(ChatDirections.actionChatToMainHost())
        }
    }
}

R.id.navigation_auth更改为Auth的ID。

这将导致:

Auth -> Details -> Chat备份到
Auth -> Main