DEV Community

Cover image for How to use Multiple Bottom-sheets in Android Compose
David
David

Posted on β€’ Edited on

12 1

How to use Multiple Bottom-sheets in Android Compose

After trying to refactor my project from the normal view system to Android Compose, I can really feel the difference between them.

I feel Android Compose will for sure become the default way to build UI in native android, but it still have a lot of cons that Google engineers are trying to solve but till then, I am gonna write on how to solve one of them in this post and it is how to have multiple bottom-sheets in the same app.

After reading this article you will easily build multiple bottom sheets as shown below.
ss

First before reading please be careful that this post applies to compose version 1.0.0-beta05.
and is definitely related to these issues:

If these two issues are not solved yet you can continue reading my post, if any of them are solved and it will change the way to support multiple bottom-sheets, I will write another post.

1- Now Let's start by defining the bottom sheets that we are gonna use in our application

sealed class BottomSheetScreen() {
    object Screen1: BottomSheetScreen()
    object Screen2: BottomSheetScreen()
    class Screen3(val argument:String):BottomSheetScreen()
}
Enter fullscreen mode Exit fullscreen mode

2- We will have a mutable state of our current sheet

@Composable
private fun MainLayout() {
  var currentBottomSheet: BottomSheetScreen? by remember{
        mutableStateOf(null)
    }
}
Enter fullscreen mode Exit fullscreen mode

3- We will use BottomSheetScaffold to handle opening and closing the bottom sheet

   val scaffoldState = rememberBottomSheetScaffoldState()
   BottomSheetScaffold(sheetPeekHeight = 0.dp, scaffoldState = scaffoldState,
        sheetShape = BottomSheetShape,
        sheetContent = {
           currentBottomSheet?.let { currentSheet ->
                SheetLayout(currentSheet,closeSheet)
            }
        }) { paddingValues ->
            Box(Modifier.padding(paddingValues)){
                MainContent(openSheet)
            }
    }
Enter fullscreen mode Exit fullscreen mode

4- Now, We will define two lambdas for opening and closing the bottom sheet

val closeSheet: () -> Unit = {
        scope.launch {
            scaffoldState.bottomSheetState.collapse()

        }
    }


    val openSheet: (BottomSheetScreen) -> Unit = {
        currentBottomSheet = it
        scope.launch { scaffoldState.bottomSheetState.expand() }

    }
    // to set the current sheet to null when the bottom sheet closes
    if(scaffoldState.bottomSheetState.isCollapsed)
        currentBottomSheet = null
Enter fullscreen mode Exit fullscreen mode

Summing it up, our code should be similar to that

@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun MainLayout() {
    val scope = rememberCoroutineScope()
    val scaffoldState = rememberBottomSheetScaffoldState()
    var currentBottomSheet: BottomSheetScreen? by remember{
        mutableStateOf(null)
    }

    val closeSheet: () -> Unit = {
        scope.launch {
            scaffoldState.bottomSheetState.collapse()
        }
    }


    val openSheet: (BottomSheetScreen) -> Unit = {
        currentBottomSheet = it
        scope.launch { scaffoldState.bottomSheetState.expand() }

    }
  if(scaffoldState.bottomSheetState.isCollapsed)
        currentBottomSheet = null

    BottomSheetScaffold(sheetPeekHeight = 0.dp, scaffoldState = scaffoldState,
        sheetShape = BottomSheetShape,
        sheetContent = {
          currentBottomSheet?.let { currentSheet ->
                SheetLayout(currentSheet,closeSheet)
            }
        }) { paddingValues ->
            Box(Modifier.padding(paddingValues)){
                MainContent(openSheet)
            }
    }
}
Enter fullscreen mode Exit fullscreen mode

5- Now we will define our SheetLayout, as we can see from the above code that it takes two parameters

  • The current bottom sheet
  • The closeSheet lambda, because if we want to have a button to close the sheet

It should be similar to that

@Composable
fun SheetLayout(currentScreen: BottomSheetScreen,onCloseBottomSheet :()->Unit) {
    BottomSheetWithCloseDialog(onCloseBottomSheet){
        when(currentScreen){
            BottomSheetScreen.Screen1 -> Screen1()
            BottomSheetScreen.Screen2 -> Screen2()
            is BottomSheetScreen.Screen3 -> Screen3(argument = currentScreen.argument)
        }

    }
}
Enter fullscreen mode Exit fullscreen mode

6- Finally last step we define MainContent composable function that takes openSheet as a parameter

@Composable
fun MainContent(openSheet: (BottomSheetScreen) -> Unit) {
    Column(Modifier.fillMaxSize(),verticalArrangement = Arrangement.SpaceEvenly,horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "This is Main Content")
        Button(onClick = { openSheet(BottomSheetScreen.Screen1) }) {
            Text(text = "Open bottom sheet 1")
        }

        Button(onClick = { openSheet(BottomSheetScreen.Screen2) }) {
            Text(text = "Open bottom sheet 2")
        }
        Button(onClick = { openSheet(BottomSheetScreen.Screen3("this is an argument")) }) {
            Text(text = "Open bottom sheet 2")
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

NB: Here is the whole project used in the Demo on Github

Thanks for reading πŸ±β€πŸ

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

Top comments (2)

Collapse
 
uwaisalqadri profile image
Uwais Alqadri β€’

cool

Collapse
 
martinaihab profile image
Martina Ihab β€’

Impressive πŸ‘ŒπŸ»

Hot sauce if you're wrong - web dev trivia for staff engineers

Hot sauce if you're wrong Β· web dev trivia for staff engineers (Chris vs Jeremy, Leet Heat S1.E4)

  • Shipping Fast: Test your knowledge of deployment strategies and techniques
  • Authentication: Prove you know your OAuth from your JWT
  • CSS: Demonstrate your styling expertise under pressure
  • Acronyms: Decode the alphabet soup of web development
  • Accessibility: Show your commitment to building for everyone

Contestants must answer rapid-fire questions across the full stack of modern web development. Get it right, earn points. Get it wrong? The spice level goes up!

Watch Video 🌢️πŸ”₯

πŸ‘‹ Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay