【问题标题】:How to prevent previous fragment to show up after pressing back button using navigation controller?使用导航控制器按下后退按钮后如何防止前一个片段显示?
【发布时间】:2023-03-05 11:53:02
【问题描述】:

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

Navigation.findNavController(view).navigate(homeDestination)

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

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

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

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

【问题讨论】:

标签: android kotlin android-navigation android-jetpack android-architecture-navigation


【解决方案1】:

导航提供了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)

您也可以使用 &lt;navigation&gt; 元素的 id。

【讨论】:

    【解决方案2】:

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

    所以我们必须在那里使用 nav Graph 的 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"/>
    

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 虽然这在某种程度上有效,但 Navigation 提供了一个内置的 popUpTo 属性,将其作为单个操作执行,而无需针对该中间状态向 OnDestinationChangedListener 发送更新。
      • 是的。这是正确的想法。我看到你的答案后来我发布了我的。你的完美。赞一个!
      【解决方案4】:

      试试这个

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

      【讨论】:

        【解决方案5】:

        显然我迟到了。尽管如此,我还是想尽我所能并扩展伊恩的答案。在app:popUpTo="@+id/destination_to_pop" 中,destination_to_pop 确实意味着您不想保留在后堆栈中的目的地。在你的情况下,loging_fragment

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-01
          • 2014-02-16
          • 1970-01-01
          • 1970-01-01
          • 2020-09-03
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多