使用导航组件实现循环逻辑的正确方法是什么
What is the correct way of implementing circular logic with the navigation component
-
android
-
android-lifecycle
-
android-fragments
-
android-architecture-components
-
android-architecture-navigation
我正在尝试使用导航组件实现循环逻辑,但我担心我没有做对并且不必要地调用了生命周期方法。
我有 1 个 activity 有 3 个片段。片段之间的导航如下所示:
A -> B -> C -> 回到 A 等..
A 和 B 是常规 Fragment,而 C 是 DialogFragment。 C 有两个按钮 - Cancel
和 Done
。如果按下 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()
,onViewCreated
,onResume()
,onDestroy()
,onDetach()
)。为什么会有差异?为什么在A中又调用了onCreate()?它不应该只使用 A 的现有实例而不是创建一个新实例吗?
我不明白为什么它会这样做,或者它是否是我应该关心的事情。我相信当用户在片段之间导航时堆栈得到适当管理,因为 C 和 A 之间的导航操作使用 popUpTo
和 popUpToInclusive
属性(如文档中推荐的 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
。
非常欢迎任何帮助消除我的困惑。
一个动作有两个步骤:
- 弹出通过
popUpTo
/ popUpToInclusive
设置的任何目的地
- 通过
app:destination
导航(即创建新实例)目的地集
操作可以是弹出、导航或两者的任意组合 - 当您右键单击目的地时导航编辑器中的 UI 和 select 新操作将为您提供每个这些选项。
因此,如果您想要一个只弹出回目的地的操作,您知道在返回堆栈中,那么您可以删除 app:destination
属性,只弹出:
<action
android:id="@+id/C_to_A"
app:popUpTo="@id/A"
app:popUpToInclusive="false" />
请注意,通过使用 app:popUpToInclusive="false"
,您可以确保 A
在执行操作后位于堆栈顶部。
android
android-lifecycle
android-fragments
android-architecture-components
android-architecture-navigation
我正在尝试使用导航组件实现循环逻辑,但我担心我没有做对并且不必要地调用了生命周期方法。
我有 1 个 activity 有 3 个片段。片段之间的导航如下所示: A -> B -> C -> 回到 A 等..
A 和 B 是常规 Fragment,而 C 是 DialogFragment。 C 有两个按钮 - Cancel
和 Done
。如果按下 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()
,onViewCreated
,onResume()
,onDestroy()
,onDetach()
)。为什么会有差异?为什么在A中又调用了onCreate()?它不应该只使用 A 的现有实例而不是创建一个新实例吗?
我不明白为什么它会这样做,或者它是否是我应该关心的事情。我相信当用户在片段之间导航时堆栈得到适当管理,因为 C 和 A 之间的导航操作使用 popUpTo
和 popUpToInclusive
属性(如文档中推荐的 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
。
非常欢迎任何帮助消除我的困惑。
一个动作有两个步骤:
- 弹出通过
popUpTo
/popUpToInclusive
设置的任何目的地
- 通过
app:destination
导航(即创建新实例)目的地集
操作可以是弹出、导航或两者的任意组合 - 当您右键单击目的地时导航编辑器中的 UI 和 select 新操作将为您提供每个这些选项。
因此,如果您想要一个只弹出回目的地的操作,您知道在返回堆栈中,那么您可以删除 app:destination
属性,只弹出:
<action
android:id="@+id/C_to_A"
app:popUpTo="@id/A"
app:popUpToInclusive="false" />
请注意,通过使用 app:popUpToInclusive="false"
,您可以确保 A
在执行操作后位于堆栈顶部。