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

Posted

技术标签:

【中文标题】用导航组件实现循环逻辑的正确方法是啥【英文标题】:What is the correct way of implementing circular logic with the navigation component用导航组件实现循环逻辑的正确方法是什么 【发布时间】:2021-04-05 17:40:00 【问题描述】:

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

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

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

我担心的是,返回 A 的每条路由都会导致在 A 中调用不同的生命周期方法。如果在用户接受 C 并按回 B 后导航返回 A,onCreateView()onViewCreated()onResume()由 A 调用。BUT,如果取消 C 后导航返回 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

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

【问题讨论】:

您在操作中使用app:destination 是否有原因(而不是忽略它并使用popUpToInclusive="false" 创建仅弹出操作)?使用app: destination 意味着您正在创建A 的新实例。 那我如何从 C 到 A?通过调用 findNavController().navigateUp() 两次? 嗯,很有趣。我只是尝试删除目标属性并将 popUpToInclusive 设置为 false,这似乎有效。 A 现在调用我期望的生命周期方法。我以为目的地是必需的?!谢谢@ianhanniballake 【参考方案1】:

一个动作有两个步骤:

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

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

因此,如果您想要一个仅弹回到您知道在后台堆栈上的目标的操作,那么您可以删除您的 app:destination 属性并且只弹出:

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

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

【讨论】:

以上是关于用导航组件实现循环逻辑的正确方法是啥的主要内容,如果未能解决你的问题,请参考以下文章

微信小程序(视图与逻辑)

在 Redux 中处理数据传递的正确方法是啥

用 JavaScript 实现手势库 — 手势逻辑前端组件化

用 JavaScript 实现手势库 — 手势逻辑前端组件化

用 Python 编写游戏循环的正确方法是啥?

从xib加载视图的正确方法是啥?