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),它又在一个单独的图中,但这次我们想清除所有的后台堆栈,因为如果用户登录并按下返回键,他希望应用程序退出,而不是让他回到 wF
或 lSF
,所以我在 [=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
上按返回时,应用程序不会关闭,而是将我带到 wF
(wF
应该已经从后台弹出了)
我试过的
我试过使用 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
,在后台你将有 loginSellerFragment
和 welcomeFragment
。
由于您使用了 popUpTo="@id/welcomeFragment"
,应用程序将开始从您的后台弹出(删除)片段,直到它到达 welcomeFragment
。 welcomeFragment
也将被删除,因为我们使用了 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()
)
所以我正在使用 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),它又在一个单独的图中,但这次我们想清除所有的后台堆栈,因为如果用户登录并按下返回键,他希望应用程序退出,而不是让他回到 wF
或 lSF
,所以我在 [=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
上按返回时,应用程序不会关闭,而是将我带到 wF
(wF
应该已经从后台弹出了)
我试过的
我试过使用 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
,在后台你将有loginSellerFragment
和welcomeFragment
。
由于您使用了 popUpTo="@id/welcomeFragment"
,应用程序将开始从您的后台弹出(删除)片段,直到它到达 welcomeFragment
。 welcomeFragment
也将被删除,因为我们使用了 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()
)