Skip to content
This repository was archived by the owner on Jan 10, 2025. It is now read-only.

Commit 27c4045

Browse files
Merge pull request #578 from googlesamples/NavAdvanced-ItemReselect
[NavigationAdvancedSample] Adds optional case for item reselected
2 parents 1c2af45 + 3f9c56c commit 27c4045

File tree

2 files changed

+62
-16
lines changed

2 files changed

+62
-16
lines changed

NavigationAdvancedSample/app/src/androidTest/java/com/example/android/navigationadvancedsample/BottomNavigationTest.kt

+18
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ class BottomNavigationTest {
113113
assertDeeperThirdScreen()
114114
}
115115

116+
@Test
117+
fun bottomNavView_itemReselected_goesBackToStart() {
118+
openThirdScreen()
119+
120+
assertThirdScreen()
121+
122+
onView(withContentDescription(R.string.sign_up))
123+
.perform(click())
124+
125+
assertDeeperThirdScreen()
126+
127+
// Reselect the current item
128+
openThirdScreen()
129+
130+
// Verify that it popped the back stack until the start destination.
131+
assertThirdScreen()
132+
}
133+
116134
private fun assertSecondScreen() {
117135
onView(allOf(withText(R.string.title_list), isDescendantOfA(withId(R.id.action_bar))))
118136
.check(matches(isDisplayed()))

NavigationAdvancedSample/app/src/main/java/com/example/android/navigationadvancedsample/NavigationExtensions.kt

+44-16
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fun BottomNavigationView.setupWithNavController(
8383
val firstFragmentTag = graphIdToTagMap[firstFragmentGraphId]
8484
var isOnFirstFragment = selectedItemTag == firstFragmentTag
8585

86-
// For the navigation item that is selected...
86+
// When a navigation item is selected
8787
setOnNavigationItemSelectedListener { item ->
8888
// Don't do anything if the state is state has already been saved.
8989
if (fragmentManager.isStateSaved) {
@@ -131,22 +131,11 @@ fun BottomNavigationView.setupWithNavController(
131131
}
132132
}
133133

134-
// handle deep link
135-
navGraphIds.forEachIndexed { index, navGraphId ->
136-
val fragmentTag = getFragmentTag(index)
134+
// Optional: on item reselected, pop back stack to the destination of the graph
135+
setupItemReselected(graphIdToTagMap, fragmentManager)
137136

138-
// Find or create the Navigation host fragment
139-
val navHostFragment = obtainNavHostFragment(
140-
fragmentManager,
141-
fragmentTag,
142-
navGraphId,
143-
containerId
144-
)
145-
// Handle Intent
146-
if (navHostFragment.navController.handleDeepLink(intent)) {
147-
this.selectedItemId = navHostFragment.navController.graph.id
148-
}
149-
}
137+
// Handle deep link
138+
setupDeepLinks(navGraphIds, fragmentManager, containerId, intent)
150139

151140
// Finally, ensure that we update our BottomNavigationView when the back stack changes
152141
fragmentManager.addOnBackStackChangedListener {
@@ -165,6 +154,45 @@ fun BottomNavigationView.setupWithNavController(
165154
return selectedNavController
166155
}
167156

157+
private fun BottomNavigationView.setupDeepLinks(
158+
navGraphIds: List<Int>,
159+
fragmentManager: FragmentManager,
160+
containerId: Int,
161+
intent: Intent
162+
) {
163+
navGraphIds.forEachIndexed { index, navGraphId ->
164+
val fragmentTag = getFragmentTag(index)
165+
166+
// Find or create the Navigation host fragment
167+
val navHostFragment = obtainNavHostFragment(
168+
fragmentManager,
169+
fragmentTag,
170+
navGraphId,
171+
containerId
172+
)
173+
// Handle Intent
174+
if (navHostFragment.navController.handleDeepLink(intent)) {
175+
this.selectedItemId = navHostFragment.navController.graph.id
176+
}
177+
}
178+
}
179+
180+
private fun BottomNavigationView.setupItemReselected(
181+
graphIdToTagMap: SparseArray<String>,
182+
fragmentManager: FragmentManager
183+
) {
184+
setOnNavigationItemReselectedListener { item ->
185+
val newlySelectedItemTag = graphIdToTagMap[item.itemId]
186+
val selectedFragment = fragmentManager.findFragmentByTag(newlySelectedItemTag)
187+
as NavHostFragment
188+
val navController = selectedFragment.navController
189+
// Pop the back stack to the start destination of the current navController graph
190+
navController.popBackStack(
191+
navController.graph.startDestination, false
192+
)
193+
}
194+
}
195+
168196
private fun detachNavHostFragment(
169197
fragmentManager: FragmentManager,
170198
navHostFragment: NavHostFragment

0 commit comments

Comments
 (0)