Fixed
Status Update
Comments
il...@google.com <il...@google.com>
il...@google.com <il...@google.com>
ap...@google.com <ap...@google.com> #2
I'd like to add that this automatic removal of the NavGraph at the top of the stack is also making it hard for me to implement proper lateral top-level navigation.
A practical case where this kind of navigation happens is with a Material Design bottom navigation bar, where I have a NavHost above the bottom bar.
Given this navigation scheme:
A - B (top-level)
B1 (first sub-level)
When starting the Activity, the back stack is
0. A
1. NavGraph
If I wanted to navigate to B laterally, I would do:
navController.popBackStack(R.id.navGraph, false)
navController.navigate(R.id.B)
But the resulting back stack is:
0. B
Now, navigating between top-level destinations actually works (though popBackStack returns false); the problem arises again if I navigate to B1:
0. B1
1. B
When navigating from B1 to a top-level destination like A, the stack becomes:
0. A
1. B1
2. B
That is, A is not a top-level destination in the back stack: if I press back from A, I intend to exit the app, but I'm taken back to B1.
It would be nice to have a fixed reference to the bottom of the stack. Right now I'm working around this with a horrible ` while (navController.popBackStack()) continue`.
A practical case where this kind of navigation happens is with a Material Design bottom navigation bar, where I have a NavHost above the bottom bar.
Given this navigation scheme:
A - B (top-level)
B1 (first sub-level)
When starting the Activity, the back stack is
0. A
1. NavGraph
If I wanted to navigate to B laterally, I would do:
navController.popBackStack(R.id.navGraph, false)
navController.navigate(R.id.B)
But the resulting back stack is:
0. B
Now, navigating between top-level destinations actually works (though popBackStack returns false); the problem arises again if I navigate to B1:
0. B1
1. B
When navigating from B1 to a top-level destination like A, the stack becomes:
0. A
1. B1
2. B
That is, A is not a top-level destination in the back stack: if I press back from A, I intend to exit the app, but I'm taken back to B1.
It would be nice to have a fixed reference to the bottom of the stack. Right now I'm working around this with a horrible ` while (navController.popBackStack()) continue`.
ap...@google.com <ap...@google.com> #3
Is this going to be fixed?
I have the same issue with a setup as follows:
Navigation graph.
<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 "
app:startDestination="@+id/startupGraph">
<navigation
android:id="@+id/startupGraph"
app:startDestination="@id/launcher_home">
<fragment
android:id="@+id/launcher_home"
android:name="com.example.android.codelabs.navigation.MainFragment"
android:label="@string/home"
tools:layout="@layout/main_fragment" />
</navigation>
<navigation
android:id="@+id/homeGraph"
app:startDestination="@id/flow_step_one">
<fragment
android:id="@+id/flow_step_one"
android:name="com.example.android.codelabs.navigation.FlowStepOneFragment"
tools:layout="@layout/flow_step_one_fragment" />
<fragment
android:id="@+id/flow_step_two"
android:name="com.example.android.codelabs.navigation.FlowStepTwoFragment"
tools:layout="@layout/flow_step_two_fragment" />
</navigation>
</navigation>
MainFragment.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.navigate_dest_bt).setOnClickListener{
Navigation.findNavController(it)
.navigate(R.id.homeGraph, null, NavOptions.Builder()
.setPopUpTo(R.id.startupGraph, false)
.build())
}
}
FlowStepOneFragment.
view.findViewById<View>(R.id.next_button).setOnClickListener {
Navigation.findNavController(it)
.navigate(R.id.flow_step_two, null, NavOptions.Builder()
.setPopUpTo(R.id.flow_step_one, true)
.build())
}
}
}
Causes the following error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.codelabs.navigation, PID: 12579
java.lang.IllegalArgumentException: Navigator androidx.navigation.fragment.FragmentNavigator@d70ec6f reported navigation to unknown destination id com.example.android.codelabs.navigation:id/flow_step_two
I have the same issue with a setup as follows:
Navigation graph.
<navigation xmlns:android="
xmlns:app="
xmlns:tools="
app:startDestination="@+id/startupGraph">
<navigation
android:id="@+id/startupGraph"
app:startDestination="@id/launcher_home">
<fragment
android:id="@+id/launcher_home"
android:name="com.example.android.codelabs.navigation.MainFragment"
android:label="@string/home"
tools:layout="@layout/main_fragment" />
</navigation>
<navigation
android:id="@+id/homeGraph"
app:startDestination="@id/flow_step_one">
<fragment
android:id="@+id/flow_step_one"
android:name="com.example.android.codelabs.navigation.FlowStepOneFragment"
tools:layout="@layout/flow_step_one_fragment" />
<fragment
android:id="@+id/flow_step_two"
android:name="com.example.android.codelabs.navigation.FlowStepTwoFragment"
tools:layout="@layout/flow_step_two_fragment" />
</navigation>
</navigation>
MainFragment.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.navigate_dest_bt).setOnClickListener{
Navigation.findNavController(it)
.navigate(R.id.homeGraph, null, NavOptions.Builder()
.setPopUpTo(R.id.startupGraph, false)
.build())
}
}
FlowStepOneFragment.
view.findViewById<View>(R.id.next_button).setOnClickListener {
Navigation.findNavController(it)
.navigate(R.id.flow_step_two, null, NavOptions.Builder()
.setPopUpTo(R.id.flow_step_one, true)
.build())
}
}
}
Causes the following error:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.codelabs.navigation, PID: 12579
java.lang.IllegalArgumentException: Navigator androidx.navigation.fragment.FragmentNavigator@d70ec6f reported navigation to unknown destination id com.example.android.codelabs.navigation:id/flow_step_two
ga...@gmail.com <ga...@gmail.com> #4
The original issue was fixed as a result of https://android-review.googlesource.com/833717 and a number of other internal changes and that will be available in alpha08.
Discovered another issue when doing this specific set of navigation actions, so leaving this open until that part is also fixed.
Discovered another issue when doing this specific set of navigation actions, so leaving this open until that part is also fixed.
fo...@google.com <fo...@google.com> #5
Project: platform/frameworks/support
Branch: androidx-master-dev
commit d3507cb9dab82264070c72a37dbde1dfb43ef578
Author: Ian Lake <ilake@google.com>
Date: Tue Dec 04 14:24:32 2018
Split pop and dispatch logic
When using popUpTo, navigate() would
internally call popBackStack(), resulting
in additional dispatch calls to
OnDestinationChangedListener before the
navigate() operation itself was done.
By separating the logic, we can ensure that
we don't prematurely remove NavGraph destinations
that should still exist after the navigate()
operation and that developers only see a
single final OnDestinationChangedListener callback.
Test: new test
BUG: 113611083
Change-Id: Ib63e4156521259a945ffecf679ccb404ac192017
M navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/runtime/src/androidTest/res/navigation/nav_nested_start_destination.xml
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
https://android-review.googlesource.com/840996
https://goto.google.com/android-sha1/d3507cb9dab82264070c72a37dbde1dfb43ef578
Branch: androidx-master-dev
commit d3507cb9dab82264070c72a37dbde1dfb43ef578
Author: Ian Lake <ilake@google.com>
Date: Tue Dec 04 14:24:32 2018
Split pop and dispatch logic
When using popUpTo, navigate() would
internally call popBackStack(), resulting
in additional dispatch calls to
OnDestinationChangedListener before the
navigate() operation itself was done.
By separating the logic, we can ensure that
we don't prematurely remove NavGraph destinations
that should still exist after the navigate()
operation and that developers only see a
single final OnDestinationChangedListener callback.
Test: new test
BUG: 113611083
Change-Id: Ib63e4156521259a945ffecf679ccb404ac192017
M navigation/runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/runtime/src/androidTest/res/navigation/nav_nested_start_destination.xml
M navigation/runtime/src/main/java/androidx/navigation/NavController.java
ap...@google.com <ap...@google.com> #6
Project: platform/frameworks/support
Branch: androidx-main
commit 64a958a72265aa72aae6dea6e78d531d0d5be096
Author: Faelyn O'Grady <fogrady@google.com>
Date: Wed Jul 21 13:20:11 2021
Fix deep link ids from a navGraph's id to one of its siblings.
For a nested NavGraph N with startDest=A, and another dest B in N:
addDestination(N)
addDestination(B)
Would previously result in:
[N, N, B]
This change fixes the result to:
[N, B]
(which implies [A, B], since A is the startDest)
Because B's buildDeepLinkIds(prevDestination = N) would generate both [N, B], even though N was already navigated to (literally set as the previousDestination).
Test: New unit tests included. All existing tests pass.
BUG: 147913689
Change-Id: I42da530ebb72be1a90164416b7ca7f95e7834bba
M navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.kt
M navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
A navigation/navigation-runtime/src/androidTest/res/navigation/nav_non_start_nest.xml
https://android-review.googlesource.com/1773621
Branch: androidx-main
commit 64a958a72265aa72aae6dea6e78d531d0d5be096
Author: Faelyn O'Grady <fogrady@google.com>
Date: Wed Jul 21 13:20:11 2021
Fix deep link ids from a navGraph's id to one of its siblings.
For a nested NavGraph N with startDest=A, and another dest B in N:
addDestination(N)
addDestination(B)
Would previously result in:
[N, N, B]
This change fixes the result to:
[N, B]
(which implies [A, B], since A is the startDest)
Because B's buildDeepLinkIds(prevDestination = N) would generate both [N, B], even though N was already navigated to (literally set as the previousDestination).
Test: New unit tests included. All existing tests pass.
BUG: 147913689
Change-Id: I42da530ebb72be1a90164416b7ca7f95e7834bba
M navigation/navigation-common/src/main/java/androidx/navigation/NavDestination.kt
M navigation/navigation-common/src/test/java/androidx/navigation/NavDestinationTest.kt
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavDeepLinkBuilderTest.kt
A navigation/navigation-runtime/src/androidTest/res/navigation/nav_non_start_nest.xml
ap...@google.com <ap...@google.com> #7
Project: platform/frameworks/support
Branch: androidx-main
commit 793e098ad770115fda31a1ae1264a62bf85ca3ec
Author: Faelyn O'Grady <fogrady@google.com>
Date: Wed Jul 21 13:24:24 2021
Use explicit task stack in navigateUp() when on another app's stack.
This change uses the synthetic task stack created by the NavDeepLinkBuilder#addDestination() API when deep-linked on top of another app's task stack when the user navigates up, rather than generating a stack based on navGraph parenting rules.
Test: New unit tests included. All existing tests pass.
Change-Id: I58f4694022fec38f8c06f5901b3001a1a700a529
BUG: 147913689
M navigation/navigation-runtime/build.gradle
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt
https://android-review.googlesource.com/1714510
Branch: androidx-main
commit 793e098ad770115fda31a1ae1264a62bf85ca3ec
Author: Faelyn O'Grady <fogrady@google.com>
Date: Wed Jul 21 13:24:24 2021
Use explicit task stack in navigateUp() when on another app's stack.
This change uses the synthetic task stack created by the NavDeepLinkBuilder#addDestination() API when deep-linked on top of another app's task stack when the user navigates up, rather than generating a stack based on navGraph parenting rules.
Test: New unit tests included. All existing tests pass.
Change-Id: I58f4694022fec38f8c06f5901b3001a1a700a529
BUG: 147913689
M navigation/navigation-runtime/build.gradle
M navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavControllerTest.kt
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavController.kt
M navigation/navigation-runtime/src/main/java/androidx/navigation/NavDeepLinkBuilder.kt
Description
When defining an explicit deep-link using NavDeepLinkBuilder, only a single Argument bundle can be provided for every Fragment destination inferred from XML. This can cause conflicts between arguments of the same name shared by different Destinations, and no argument verification is performed, so it's possible for parent Fragments to crash at navigateUp() time.
Request: A NavDeepLinkBuilder api that allows composition of explicit [destId, args] pairs to construct a destination stack. Preferably, accepting NavDirections as the parameter, so existing SafeArgs generated wrappers can be reused for argument safety.