I have an app which requires multiple paired devices. From the flow of the app, there are multiple places where you can initialize pairing flow.
So I have the pairing flow as nested graph, and in root graph, I have a global action pairing_action
. And inside the nested graph, I have another global action finish_pairing
.
The problem is, when I call finish_pairing
action from the pairing fragments, I always ends up at the main screen regardless from where I initiated the pairing flow.
But that's not what I want, I want to get back to the screen where I initiated the pairing flow from (where I left off when entering the pairing flow).
Code given below.
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>
nested pairing nav graph
EDIT 1:
I get back to the main screen even when I press back button from the pairing flow.
Example: I get to the pairing screen like this:
main -> devices -> pairing -> enter code
Now when I call the finish_pairing
global action from enter code
screen (or press back 2 time), I want to return back to the devices
screen. But I end up on the main
instead.
EDIT 2:
This is the logcat when going from devices
screen to pairing graph
:
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...
It seems that when navigating to pairing graph
, backstack was popped (first devices
screen then start
screen) and then go to pairing
screen.
Isn't it a bug? Why should global action pop backstack?!
I am using options menu items to get into the pairing flow.
I use menu navigation heavily in my app. NavigationUI supports it. But if you read the documentation carefuly, there is this little remark:
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.
And this was the reason why entering pairing screens from devices screens "broke" the back stack.
So the solution was adding android:menuCategory="secondary"
to the menu on devices screen, and it started working as expected.