在导航表单选项菜单项时导航到嵌套图时如何返回用户离开的位置?
How to get back where user left off when navigated to a nested graph when navigated form option menu item?
我有一个需要多个配对设备的应用程序。从应用程序的流程来看,有多个地方可以初始化配对流程。
所以我将配对流作为嵌套图,在 根图 中,我有一个全局操作 pairing_action
。在嵌套图中,我有另一个全局操作 finish_pairing
.
问题是,当我从配对片段调用 finish_pairing
操作时,无论我从哪里启动配对流程,我总是会在主屏幕上结束。
但这不是我想要的,我想返回到我从启动配对流程的屏幕(进入配对流程时我离开的地方)。
代码如下。
navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/start_fragment">
<!-- Global action to start pairing -->
<action android:id="@+id/pairing_action"
app:destination="@id/pairing"/>
<fragment ... />
<fragment ... />
<fragment ... />
<!-- Nested pairing flow -->
<navigation android:id="@+id/pairing"
android:label="Pairing"
app:startDestination="@id/pairing_fragment">
<!-- Nested global action to finish pairing -->
<!-- Should get to the fragment which initiated pairing! -->
<action android:id="@+id/finish_pairing"
app:popUpTo="@id/pairing"
app:popUpToInclusive="true" />
<fragment ... />
<fragment ... />
<fragment ... />
</navigation>
</navigation>
嵌套配对导航图
编辑 1:
即使我在配对流程中按下后退按钮,我也会返回主屏幕。
示例:我进入配对屏幕是这样的:
main -> devices -> pairing -> enter code
现在,当我从 enter code
屏幕调用 finish_pairing
全局操作时(或按返回键 2 次),我想 return 返回到 devices
屏幕。但我最终选择了 main
。
编辑 2:
这是从 devices
屏幕转到 pairing graph
时的 logcat:
V/FragmentManager: Commit: BackStackEntry...
D/FragmentManager: mName=2-2131231057 mIndex=-1 mCommitted=false
...
D/FragmentManager: Operations:
D/FragmentManager: Op #0: REPLACE PairingFragment...
...
D/FragmentManager: Op #1: SET_PRIMARY_NAV PairingFragment...
...
V/FragmentManager: Run: BackStackEntry...
V/FragmentManager: Bump nesting in BackStackEntry... by -1
V/FragmentManager: Bump nesting of StartFragment... to 1
V/FragmentManager: Bump nesting of StartFragment... to 0
V/FragmentManager: Bump nesting of DevicesFragment... to 1
V/FragmentManager: Bump nesting of DevicesFragment... to 0
V/FragmentManager: remove: DevicesFragment... nesting=0
V/FragmentManager: add: StartFragment...
V/FragmentManager: Bump nesting in BackStackEntry... by 1
V/FragmentManager: Bump nesting of StartFragment... to 1
V/FragmentManager: Bump nesting of StartFragment... to 2
V/FragmentManager: Bump nesting of PairingFragment... to 1
V/FragmentManager: Bump nesting of PairingFragment... to 2
V/FragmentManager: remove: StartFragment... nesting=2
V/FragmentManager: add: PairingFragment...
V/FragmentManager: Added fragment to active set PairingFragment...
V/FragmentManager: moveto CREATED: PairingFragment...
V/FragmentManager: moveto ACTIVITY_CREATED: PairingFragment...
V/FragmentManager: moveto STARTED: PairingFragment...
V/FragmentManager: moveto RESUMED: PairingFragment...
V/FragmentManager: movefrom RESUMED: DevicesFragment...
V/FragmentManager: movefrom STARTED: DevicesFragment...
V/FragmentManager: movefrom ACTIVITY_CREATED: DevicesFragment...
W/FragmentManager: moveToState: Fragment state for DevicesFragment... not updated inline; expected state 1 found 2
V/FragmentManager: movefrom CREATED: DevicesFragment...
D/FragmentManager: Clearing non-config state for DevicesFragment...
D/FragmentManager: onCleared called for FragmentManagerViewModel{a60610c} Fragments () Child Non Config () ViewModelStores ()
V/FragmentManager: Removed fragment from active set DevicesFragment...
似乎在导航到 pairing graph
时弹出了后台堆栈(首先是 devices
屏幕,然后是 start
屏幕),然后转到 pairing
屏幕。
这不是一个错误吗? global action 为什么要pop backstack?!
我正在使用选项菜单项进入配对流程。
只需从嵌套图创建一个常规 action 并设置 popUpTo
嵌套图本身。
<action
android:id="@+id/action_pairing_nav_graph_self"
app:popUpTo="@+id/pairing_nav_graph" />
设计
XML
<navigation...
android:id="@+id/nav_graph.xml"
app:startDestination="@id/fragmentMain">
<fragment...>
<action.../>
<action.../>
<action.../>
</fragment>
<fragment...>
<action.../>
</fragment>
<fragment...>
<action.../>
</fragment>
<!-- nested graph -->
<navigation
android:id="@+id/pairing_nav_graph"
...>
<fragment ...>
<fragment...>
<action.../>
</fragment>
<!-- action to the graph itself -->
<action
android:id="@+id/action_pairing_nav_graph_self"
app:popUpTo="@+id/pairing_nav_graph"
/>
</navigation>
</navigation>
我在我的应用程序中大量使用菜单导航。 NavigationUI supports it. But if you read the documentation 小心一点,有一点备注:
By default, the back stack will be popped back to the navigation graph's start destination. Menu items that have android:menuCategory="secondary"
will not pop the back stack.
这就是为什么从设备屏幕 "broke" 返回堆栈进入配对屏幕的原因。
所以解决方案是将 android:menuCategory="secondary"
添加到设备屏幕上的菜单,它开始按预期工作。
我有一个需要多个配对设备的应用程序。从应用程序的流程来看,有多个地方可以初始化配对流程。
所以我将配对流作为嵌套图,在 根图 中,我有一个全局操作 pairing_action
。在嵌套图中,我有另一个全局操作 finish_pairing
.
问题是,当我从配对片段调用 finish_pairing
操作时,无论我从哪里启动配对流程,我总是会在主屏幕上结束。
但这不是我想要的,我想返回到我从启动配对流程的屏幕(进入配对流程时我离开的地方)。
代码如下。
navigation.xml
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation"
app:startDestination="@id/start_fragment">
<!-- Global action to start pairing -->
<action android:id="@+id/pairing_action"
app:destination="@id/pairing"/>
<fragment ... />
<fragment ... />
<fragment ... />
<!-- Nested pairing flow -->
<navigation android:id="@+id/pairing"
android:label="Pairing"
app:startDestination="@id/pairing_fragment">
<!-- Nested global action to finish pairing -->
<!-- Should get to the fragment which initiated pairing! -->
<action android:id="@+id/finish_pairing"
app:popUpTo="@id/pairing"
app:popUpToInclusive="true" />
<fragment ... />
<fragment ... />
<fragment ... />
</navigation>
</navigation>
嵌套配对导航图
编辑 1:
即使我在配对流程中按下后退按钮,我也会返回主屏幕。
示例:我进入配对屏幕是这样的:
main -> devices -> pairing -> enter code
现在,当我从 enter code
屏幕调用 finish_pairing
全局操作时(或按返回键 2 次),我想 return 返回到 devices
屏幕。但我最终选择了 main
。
编辑 2:
这是从 devices
屏幕转到 pairing graph
时的 logcat:
V/FragmentManager: Commit: BackStackEntry...
D/FragmentManager: mName=2-2131231057 mIndex=-1 mCommitted=false
...
D/FragmentManager: Operations:
D/FragmentManager: Op #0: REPLACE PairingFragment...
...
D/FragmentManager: Op #1: SET_PRIMARY_NAV PairingFragment...
...
V/FragmentManager: Run: BackStackEntry...
V/FragmentManager: Bump nesting in BackStackEntry... by -1
V/FragmentManager: Bump nesting of StartFragment... to 1
V/FragmentManager: Bump nesting of StartFragment... to 0
V/FragmentManager: Bump nesting of DevicesFragment... to 1
V/FragmentManager: Bump nesting of DevicesFragment... to 0
V/FragmentManager: remove: DevicesFragment... nesting=0
V/FragmentManager: add: StartFragment...
V/FragmentManager: Bump nesting in BackStackEntry... by 1
V/FragmentManager: Bump nesting of StartFragment... to 1
V/FragmentManager: Bump nesting of StartFragment... to 2
V/FragmentManager: Bump nesting of PairingFragment... to 1
V/FragmentManager: Bump nesting of PairingFragment... to 2
V/FragmentManager: remove: StartFragment... nesting=2
V/FragmentManager: add: PairingFragment...
V/FragmentManager: Added fragment to active set PairingFragment...
V/FragmentManager: moveto CREATED: PairingFragment...
V/FragmentManager: moveto ACTIVITY_CREATED: PairingFragment...
V/FragmentManager: moveto STARTED: PairingFragment...
V/FragmentManager: moveto RESUMED: PairingFragment...
V/FragmentManager: movefrom RESUMED: DevicesFragment...
V/FragmentManager: movefrom STARTED: DevicesFragment...
V/FragmentManager: movefrom ACTIVITY_CREATED: DevicesFragment...
W/FragmentManager: moveToState: Fragment state for DevicesFragment... not updated inline; expected state 1 found 2
V/FragmentManager: movefrom CREATED: DevicesFragment...
D/FragmentManager: Clearing non-config state for DevicesFragment...
D/FragmentManager: onCleared called for FragmentManagerViewModel{a60610c} Fragments () Child Non Config () ViewModelStores ()
V/FragmentManager: Removed fragment from active set DevicesFragment...
似乎在导航到 pairing graph
时弹出了后台堆栈(首先是 devices
屏幕,然后是 start
屏幕),然后转到 pairing
屏幕。
这不是一个错误吗? global action 为什么要pop backstack?!
我正在使用选项菜单项进入配对流程。
只需从嵌套图创建一个常规 action 并设置 popUpTo
嵌套图本身。
<action
android:id="@+id/action_pairing_nav_graph_self"
app:popUpTo="@+id/pairing_nav_graph" />
设计
XML
<navigation...
android:id="@+id/nav_graph.xml"
app:startDestination="@id/fragmentMain">
<fragment...>
<action.../>
<action.../>
<action.../>
</fragment>
<fragment...>
<action.../>
</fragment>
<fragment...>
<action.../>
</fragment>
<!-- nested graph -->
<navigation
android:id="@+id/pairing_nav_graph"
...>
<fragment ...>
<fragment...>
<action.../>
</fragment>
<!-- action to the graph itself -->
<action
android:id="@+id/action_pairing_nav_graph_self"
app:popUpTo="@+id/pairing_nav_graph"
/>
</navigation>
</navigation>
我在我的应用程序中大量使用菜单导航。 NavigationUI supports it. But if you read the documentation 小心一点,有一点备注:
By default, the back stack will be popped back to the navigation graph's start destination. Menu items that have
android:menuCategory="secondary"
will not pop the back stack.
这就是为什么从设备屏幕 "broke" 返回堆栈进入配对屏幕的原因。
所以解决方案是将 android:menuCategory="secondary"
添加到设备屏幕上的菜单,它开始按预期工作。