https://kotlinlang.org logo
#compose
Title
# compose
p

Piotr Prus

08/03/2022, 10:24 AM
I am using material navigation and bottomSheet composable in navGraph. Everything working ok so far, except one thing. The bottomSheet automatically closes when I navigate to another destination. I would like to keep it open (remember its state) when coming back to the screen with bottomSheet. Video and code in the 🧵 👇
Copy code
@OptIn(ExperimentalMaterialNavigationApi::class, ExperimentalMaterialApi::class)
@Composable
fun NavigationTest() {
    val bottomSheetNavigator = rememberBottomSheetNavigator()
    val navController = rememberNavController(bottomSheetNavigator)

    com.google.accompanist.navigation.material.ModalBottomSheetLayout(
        scrimColor = Color.Unspecified,
        bottomSheetNavigator = bottomSheetNavigator
    ) {
        NavHost(navController = navController, startDestination = "home") {
            composable("home") {
                Scaffold { paddingValues ->
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .background(Color.Gray)
                            .padding(paddingValues)
                    ) {
                        Button(onClick = { navController.navigate("detail") }) {
                            Text(text = "Open detail")
                        }
                    }
                }
            }
            bottomSheet("detail") {
                Column {
                    Button(onClick = { navController.navigate("test") }) {
                        Text(text = "Navigate to screen")
                    }
                    repeat(20) {
                        Text(modifier = Modifier.padding(8.dp), text = "This is detail: $it")
                    }
                }
            }
            composable("test") {
                Scaffold { paddingValues ->
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .background(Color.Blue)
                            .padding(paddingValues)
                    )
                }
            }
        }
    }
}
c

Colton Idle

08/03/2022, 12:39 PM
I think that's by design. The nav docs show that all modal destinations will close when navigating to another destination IIRC. i can try to find the docs when im at my desk.
p

Piotr Prus

08/03/2022, 12:41 PM
Thanks for info. Good to know that this is the design, however I still need to find the solution to remember the state.
c

Colton Idle

08/03/2022, 12:59 PM
Instead of using a bottom sheet as a destination you could just include the bottom sheet in your layout directly.
thats what i do
p

Piotr Prus

08/03/2022, 1:34 PM
I need to rethink the design and architecture in that case. My bottomSheet has its own VM and the reason behind that is we are using KMM, so this VM is used by modal view in iOS as well.
@jossiwolf, is there any way to make bottomSheet state remembered when using navigation as described above ?
j

jossiwolf

08/05/2022, 8:46 AM
This is by design, yes. Sheets are floating window destinations:
Destinations that implement this interface will automatically be popped off the back stack when you navigate to a new destination.
UX-wise it feels a bit weird to go from a non-floating destination back to a floating destination. We don't support it, sorry!
p

Piotr Prus

08/05/2022, 9:05 AM
I see. However there are usecases, where bottomSheet have some important informations that you want to keep on screen till user deside to close it. For example Google Maps has such a feature. Click on
Discover
, the bottomSheet will appear with a lot of content. After clicking in one of items the app opens new destination, but when you go back, the discover(bottomSheet) is still opened. I am looking for such behaviour.
j

jossiwolf

08/05/2022, 10:27 AM
Google Maps uses a standard bottom sheet, Accompanist offers support for modal sheets🙂 Standard sheets work well for secondary content while modal sheets usually present a set of choices while blocking interaction with the rest of the screen. Do standard sheets fit your use case better?
p

Piotr Prus

08/05/2022, 10:38 AM
Probably. I was experimenting with
BottomSheetScaffold
, but I found navigation with modal bottom sheet way more convenient to use. Also, the BottomSheet from scaffold do not have the
halfExpanded
state which is very important for me. Probably I need something hybrid, but basically I would like to mimc the behaviour of the
discover
panel from google maps. What is the recommended way to do that with Compose?
j

jossiwolf

08/05/2022, 10:59 AM
Modal sheets work well with navigation because they are modals and can be presented independently. If you only need a standard bottom sheet on one screen to display secondary content, use
BottomSheetScaffold
. Material has set rules for the states that standard bottom sheets can be in. If you want to have custom states I would recommend building your own sheet using Swipeable🙂 This is an area we're looking to improve so if you miss any building blocks let us know!
p

Piotr Prus

08/05/2022, 1:14 PM
Thanks for clarification. I will play with swipeable 🙂
229 Views