【问题标题】:popUpTo seems not to work in Navigation ComponentpopUpTo 似乎在导航组件中不起作用
【发布时间】:2020-01-22 09:44:12
【问题描述】:

所以我使用的是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 后,backstack 如下所示:wF lSF

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

<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" 并且效果很好,但我很确定这不是应该的方式。我在这里想念什么?我是否构建了错误的后台堆栈?

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

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

【问题讨论】:

    标签: android android-fragments android-navigation


    【解决方案1】:

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

    您在问题中提到的解决方案是正确的: 您确实应该使用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 导航回来,您将退出应用程序,因为您的后台堆栈为空。

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

    【讨论】:

    • 实际上我开始调试一点导航组件,得出的结论是“我错了说我错了”:))。事实上,最初我认为popUpTo 它将开始从图的根部弹出元素,直到它到达片段,但它实际上以相反的方式表现(它从添加的最新片段开始,直到它到达指定的片段. 我仍然觉得这个反直觉,但很高兴有人终于解释了它。
    • 我确实有一个问题,我记录了onCreateonDestroy,它似乎首先破坏了loginSellerFragment,然后是welcomeFragment。以下是日志:14:56:55.898 WelcomeFragment is destroyed 14:56:55.907 SellerLoginFragment is destroyed。这是什么原因?
    • 如果您遵循我的回答的后半部分,那就是它们应该被销毁的顺序。首先是loginSellerFragment,然后是welcomeFragment。不要混淆的一件事:片段的弹出与图形无关,而是与回栈有关。
    • 我也觉得这很不直观。我知道他们想使用“up to”,但它是一个堆栈,所以“up”实际上是针对最近的,但同时,android 在“up=previous”上运行,所以存在矛盾(如果我'我没有记错)和混乱。
    【解决方案2】:

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

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

    【讨论】:

    • 对我来说也一样。我有同样的问题,你的解决方案救了我。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多