使用导航控制器按下后退按钮后如何防止上一个片段出现?

How to prevent previous fragment to show up after pressing back button using navigation controller?

我现在正在尝试使用导航控制器。我想从 LoginFragment 移动到 HomeFragment。在 LoginFragment 中,我使用下面的代码移动到 HomeFragment

Navigation.findNavController(view).navigate(homeDestination)

但是,当我点击 HomeFragment 中的后退按钮时,它会返回 LoginFragment,我希望当我点击该按钮时它会关闭应用程序。

以旧方式,如果我使用 activity 而不是使用 Fragment,我通常会这样做以获得预期的行为:

val intent = Intent(this,HomeActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK.or(Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)

通过使用这些标志,我获得了预期的行为。但是我不知道如何使用导航控制器实现相同的行为。

Navigation 提供了 popUpTopopUpToInclusive 属性,用于在 navigate() 操作中从返回堆栈中删除片段。

这可以在 XML:

中设置
<!-- Add to your Navigation XML, then use navigate(R.id.go_home) -->
<action
  android:id="@+id/go_home"
  app:destination="@+id/home_fragment"
  app:popUpTo="@+id/destination_to_pop"
  app:popUpToInclusive="true"/>

或以编程方式设置:

NavOptions navOptions = new NavOptions.Builder()
    .setPopUpTo(R.id.destination_to_pop, true)
    .build();
Navigation.findNavController(view).navigate(homeDestination, navOptions)

您也可以使用 <navigation> 元素的 ID。

我认为这应该可以解决问题。

NavController controller = Navigation.findNavController(view);
controller.popBackStack(R.id.fragmentLogin, true);
controller.navigate(homeDestination)

我一直在关注 Ian 的回答,但我一直运气不好,因为我不知道 popUpTo 是什么。

所以我们必须在那里使用导航图的id。

app:popUpTo="@+id/idOfNavGraph". //id of nav graph

<action
  android:id="@+id/go_home"
  app:destination="@+id/home_fragment"
  app:popUpTo="@+id/idOfNavGraph". //id of nav graph
  app:popUpToInclusive="true"/>

试试这个

 val c = view.findNavController()
 c.popBackStack() // current fragment will be pop up from the stack
 c.navigate(DestinationFragmentID)

显然我迟到了。尽管如此,我还是想尽我的一份力量来扩展 Ian 的回答。在 app:popUpTo="@+id/destination_to_pop" 中,destination_to_pop 的真正意思是您不想保留在后台堆栈中的目的地。在你的情况下,loging_fragment.

这样,当您从 HomeFragment 返回时,应用程序将关闭,因为 LoginFragment 不再位于后台堆栈中。你可以找到相关的官方文档 here.