popUpTo 似乎不适用于导航组件

popUpTo seems not to work in Navigation Component

所以我正在使用 android 导航组件,但我遇到了问题(2.2.0-rc04 版本)。

我有一个 welcomeFragment(wF)。我想从 wF 导航到位于不同导航图中的 loginSellerFragment(lSF)。我也不想在导航到 lSF 时从后台堆栈(popUpTo、popUpToInclusive)中删除 wF,因为用户可能想返回它。

<fragment
    android:id="@+id/welcomeFragment">
    <action
        android:id="@+id/action_welcomeFragment_to_nav_onboarding_seller"
        app:launchSingleTop="true"
        app:destination="@id/nav_onboarding_seller" />
</fragment>

导航到 lSF 后,后台堆栈如下所示:wF lSF

我们现在在 lSF,登录后我们想去 feedFragment(fF),它又在一个单独的图中,但这次我们想清除所有的后台堆栈,因为如果用户登录并按下返回键,他希望应用程序退出,而不是让他回到 wFlSF,所以我在 [=16] 的操作中使用了 popUpTo="@id/loginSellerFragment popUpToInclusive='true" =] 到 fF.

<fragment
    android:id="@+id/loginSellerFragment">
    <action
        android:id="@+id/action_login_to_seller"
        app:destination="@+id/seller" . //this is the graph that has as firstDestination, feedFragment
        app:launchSingleTop="true"
        app:popUpTo="@id/loginSellerFragment"
        app:popUpToInclusive="true" />
</fragment>

所以此时在后台应该只有 fF 因为我们删除了 lSF(包括 lSF

之前的所有内容

问题

当我在 fF 上按返回时,应用程序不会关闭,而是将我带到 wFwF 应该已经从后台弹出了)

我试过的

我试过使用 popUpTo="@id/welcomeFragment popUpToInclusive='true" 而不是 popUpTo="@id/loginSellerFragment popUpToInclusive='true" 并且效果很好,但我很确定这不是应该的做法。伙计们,我在这里想念什么?我构建的 backstack 是不是错了?

我还尝试在从 wF 导航到 lSF 后添加 popUpTo="@id/welcomeFragment popUpToInclusive='true" ,但这会破坏我的用户体验,因为我不希望应用程序在以下情况下退出我还在登录过程中。

请注意,所有这些片段都在单独的图表中。 为了导航,我使用 FragmentDirections 例如:findNavController.navigate(WelcomeFramgentDirections.actionXtoY())

当您使用 popUpTo 选项时,要掌握导航组件如何操作返回堆栈并不容易。

你在问题中提到的解决方案是正确的: 你确实应该使用 popUpTo="@id/welcomeFragment" popUpToInclusive="true" 而不是 popUpTo="@id/loginSellerFragment" popUpToInclusive="true".

我会尽力解释原因。

  • 当您启动您的应用程序时,您的后台堆栈将为空,并且将显示 welcomeFragment

  • 当您从 welcomeFragment 导航到 loginSellerFragment 时,您的后台堆栈中将有 welcomeFragment

  • 如果你登录,你将从 loginSellerFragment 导航到 feedFragment,在后台你将有 loginSellerFragmentwelcomeFragment

由于您使用了 popUpTo="@id/welcomeFragment",应用程序将开始从您的后台弹出(删除)片段,直到它到达 welcomeFragmentwelcomeFragment 也将被删除,因为我们使用了 popUpToInclusive="true"

Backstack 的行为应该类似于 FILO(先进后出)堆栈,因此它将以这种方式删除片段:

首先将删除顶部片段,即 loginSellerFragment

接下来,welcomeFragment 将是顶部片段。因为我们需要弹出片段直到我们到达 welcomeFragment 这是我们停止的地方,但是 welcomeFragment 也会因为 popUpToInclusive="true" 而被删除并且你的后台将是空的。

如果您尝试从 welcomeFragment 导航回来,您将退出应用程序,因为您的后台堆栈是空的。

希望对您有所帮助。您还可以阅读有关堆栈数据结构的更多信息。

对我来说设置XML代码并没有真正解决问题,不得不使用额外的代码行

  findNavController()
                .navigate(R.id.navigationFragment,
                    null,
                    NavOptions.Builder()
                        .setPopUpTo(R.id.splashFragment,
                            true).build()
                )