summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Woods <jbwoods@google.com>2023-12-20 19:40:53 +0000
committerJeremy Woods <jbwoods@google.com>2023-12-20 19:40:53 +0000
commitc2802818656fffd625ea277eeb9fd06bad7e2480 (patch)
treeb55391a687488415e5304c992a5bb3b27529644a
parentd1e347560bc9c269a4bc4ed398f40ab6f613d78b (diff)
downloadaccompanist-c2802818656fffd625ea277eeb9fd06bad7e2480.tar.gz
Ensure Navigation Material properly handles back for nested nav
If there is a nested NavGraph under the current bottomSheet destination and you do a back press, instead of the bottomSheet which is the topmost destination being popped, the nested NavHost underneath will be popped instead. This is caused by bottomSheet not properly intercepting back presses. This change added a BackHandler to ensure that bottomsheets correctly respect the system back hierarchy for back events. Fixes: #1726
-rw-r--r--navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt65
-rw-r--r--navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt5
2 files changed, 70 insertions, 0 deletions
diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt
index 915d4f39..7bad7972 100644
--- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt
+++ b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/BottomSheetNavigatorTest.kt
@@ -779,6 +779,71 @@ internal class BottomSheetNavigatorTest {
.isEqualTo(firstSheetDestination)
}
+ @Test
+ fun testBackPressWithNestedGraphBehind() {
+ lateinit var navigator: BottomSheetNavigator
+ lateinit var navController: NavHostController
+ lateinit var nestedNavController: NavHostController
+ lateinit var backDispatcher: OnBackPressedDispatcher
+ val homeDestination = "home"
+ val firstSheetDestination = "sheet1"
+ val firstNestedDestination = "nested1"
+ val secondNestedDestination = "nested2"
+
+ composeTestRule.setContent {
+ backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher!!
+ navigator = rememberBottomSheetNavigator()
+ navController = rememberNavController(navigator)
+ ModalBottomSheetLayout(navigator) {
+ NavHost(navController, homeDestination) {
+ composable(homeDestination) {
+ nestedNavController = rememberNavController()
+ NavHost(nestedNavController, "nested1") {
+ composable(firstNestedDestination) { }
+ composable(secondNestedDestination) { }
+ }
+ }
+ bottomSheet(firstSheetDestination) {
+ Text("SheetDestination")
+ }
+ }
+ }
+ }
+
+ assertThat(navController.currentBackStackEntry?.destination?.route)
+ .isEqualTo(homeDestination)
+
+ composeTestRule.runOnUiThread {
+ nestedNavController.navigate(secondNestedDestination)
+ }
+ composeTestRule.waitForIdle()
+
+ assertThat(navController.currentBackStackEntry?.destination?.route)
+ .isEqualTo(homeDestination)
+ assertThat(nestedNavController.currentBackStackEntry?.destination?.route)
+ .isEqualTo(secondNestedDestination)
+
+ composeTestRule.runOnUiThread {
+ navController.navigate(firstSheetDestination)
+ }
+ composeTestRule.waitForIdle()
+
+ assertThat(navigator.sheetState.currentValue)
+ .isAnyOf(ModalBottomSheetValue.HalfExpanded, ModalBottomSheetValue.Expanded)
+
+ composeTestRule.runOnUiThread {
+ backDispatcher.onBackPressed()
+ }
+ composeTestRule.waitForIdle()
+
+ assertThat(navController.currentBackStackEntry?.destination?.route)
+ .isEqualTo(homeDestination)
+ assertThat(nestedNavController.currentBackStackEntry?.destination?.route)
+ .isEqualTo(secondNestedDestination)
+
+ assertThat(navigator.sheetState.currentValue).isEqualTo(ModalBottomSheetValue.Hidden)
+ }
+
private fun BottomSheetNavigator.createFakeDestination() =
BottomSheetNavigator.Destination(this) {
Text("Fake Sheet Content")
diff --git a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt b/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt
index 932fc07c..d514747d 100644
--- a/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt
+++ b/navigation-material/src/main/java/com/google/accompanist/navigation/material/BottomSheetNavigator.kt
@@ -17,6 +17,7 @@
package com.google.accompanist.navigation.material
import android.annotation.SuppressLint
+import androidx.activity.compose.BackHandler
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.material.ExperimentalMaterialApi
@@ -212,6 +213,10 @@ class BottomSheetNavigator(
LaunchedEffect(retainedEntry) {
sheetState.show()
}
+
+ BackHandler {
+ state.popWithTransition(popUpTo = retainedEntry!!, saveState = false)
+ }
}
SheetContentHost(