使用导航组件实现循环逻辑的正确方法是什么

What is the correct way of implementing circular logic with the navigation component

我正在尝试使用导航组件实现循环逻辑,但我担心我没有做对并且不必要地调用了生命周期方法。

我有 1 个 activity 有 3 个片段。片段之间的导航如下所示: A -> B -> C -> 回到 A 等..

A 和 B 是常规 Fragment,而 C 是 DialogFragment。 C 有两个按钮 - CancelDone。如果按下 Cancel,将调用导航操作(使用 findNavController().navigate(<action>)),应用程序将显示 A。如果按下 Done,则关闭 C,应用程序将显示 B 和用户然后可以通过按返回 return 到 A。这一切都如我所料,但是...

我担心的是,返回 A 的每个路由都会导致在 A 中调用不同的生命周期方法。如果在用户接受 C 并按回 B 后导航 returns 到 A,onCreateView()onViewCreated()onResume()被A调用。但是,如果C取消后导航return到A,A会调用更多的生命周期方法(onAttach()onCreate()onCreateView()onViewCreatedonResume()onDestroy()onDetach())。为什么会有差异?为什么在A中又调用了onCreate()?它不应该只使用 A 的现有实例而不是创建一个新实例吗?

我不明白为什么它会这样做,或者它是否是我应该关心的事情。我相信当用户在片段之间导航时堆栈得到适当管理,因为 C 和 A 之间的导航操作使用 popUpTopopUpToInclusive 属性(如文档中推荐的 here ) .我也尝试在 C 和 A 之间的操作中设置 launchSingleTop 属性,但我得到了相同的行为(在 A 中调用了额外的生命周期方法)。

这是 C 片段的 xml:

<dialog
    android:id="@+id/C"
    android:name="C"
    ... >
    <action
        android:id="@+id/C_to_A"
        app:destination="@id/A"
        app:popUpTo="@id/A"
        app:popUpToInclusive="true" />
</dialog>

当用户按下 cancel 按钮时,我从 C 调用操作 C_to_A

非常欢迎任何帮助消除我的困惑。

一个动作有两个步骤:

  1. 弹出通过 popUpTo / popUpToInclusive
  2. 设置的任何目的地
  3. 通过 app:destination
  4. 导航(即创建新实例)目的地集

操作可以是弹出、导航或两者的任意组合 - 当您右键单击目的地时导航编辑器中的 UI 和 select 新操作将为您提供每个这些选项。

因此,如果您想要一个只弹出回目的地的操作,您知道在返回堆栈中,那么您可以删除 app:destination 属性,只弹出:

<action
        android:id="@+id/C_to_A"
        app:popUpTo="@id/A"
        app:popUpToInclusive="false" />

请注意,通过使用 app:popUpToInclusive="false",您可以确保 A 在执行操作后位于堆栈顶部。