androidkotlinmodal-dialogandroid-jetpack-composefullscreen

Koltin Jetpack compose, ModalBottomSheetLayout stop in the middle of the screen


I'am new to jetpack compose and i really liked it. But ran into a problem : I to have a modal that take all my screen size, following multiples tutorial i was able to do it using ModalBottomSheetLayout, Here is my code :

@ExperimentalMaterialApi
@Composable
fun DetailsScreen() {
    val coroutineScope = rememberCoroutineScope()
    val sheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)

    ModalBottomSheetLayout(
        sheetContent = {
            Box(
                modifier = Modifier
                    .navigationBarsWithImePadding()
                    .fillMaxSize()
                    .wrapContentHeight() //changed here to have full screen size, but it was only half screen, i had to slide with my finger to make the modal to full screen
                    //.height(200.dp) initial value i have a little modal on the bottom
                    //.fillMaxWidth()
                    .background(Color.White)
            ) {
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .padding(10.dp)
                ) {
                    Text(
                        text = "Bottom Sheet",
                        textAlign = TextAlign.Center,
                        style = MaterialTheme.typography.h5,
                        fontWeight = FontWeight.Bold,
                        modifier = Modifier.fillMaxWidth()
                    )
                    Text(
                        text = "Item 1",
                        style = MaterialTheme.typography.h6,
                        modifier = Modifier.padding(top = 10.dp)
                    )
                    Text(
                        text = "Item 2",
                        style = MaterialTheme.typography.h6,
                        modifier = Modifier.padding(top = 10.dp)
                    )
                    Text(
                        text = "Item 3",
                        style = MaterialTheme.typography.h6,
                        modifier = Modifier.padding(top = 10.dp)
                    )
                }
            }
        },
        sheetState = sheetState,
        sheetBackgroundColor = Color.White
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = {
                        Text(
                            text = "Modal Bottom Sheet",
                            modifier = Modifier.fillMaxWidth(),
                            textAlign = TextAlign.Center
                        )
                    }
                )
            }
        ) {
            MainContent(
                onClick = {
                    coroutineScope.launch {
                        //sheetState.show() // changed here make the modal full screen at the beginning
                        sheetState.animateTo(ModalBottomSheetValue.Expanded)
                    }
                },
                modifier = Modifier.padding(it)
            )
        }
    }
}

@Composable
fun MainContent(
    onClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    Box(
        contentAlignment = Alignment.Center,
        modifier = modifier.fillMaxSize()
    ) {
        Button(
            onClick = onClick,
            shape = RoundedCornerShape(10.dp)
        ) {
            Text(
                text = "Click Me!",
                textAlign = TextAlign.Center,
                style = MaterialTheme.typography.h6.copy(color = Color.White)
            )
        }
    }
}

Problem i encounter : at first the modal was just at the bottom so i made my box to fillMaxSize to make it full screen, but it only open to half screen and i slide to swipe up to make it full screen.

Then i found that i could change sheetState.show() to sheetState.animateTo(ModalBottomSheetValue.Expanded) to make my modal full screen from the moment it display. Perfect it's what i wanted. here is a screen of the modal : Modal full screen

The problem is that now when i slide down to dismiss the modal it's stop half scree as bellow:

Modal half screen

From there i have to swipe down an other time to make it disappear. Also when it's on the middle i can swipe up to make it back to full screen. It's seem that there is 3 states: fullscreen, halfscreen, and gone. And the modal can be full screen or halfscreen. I would like to remove the half screen. So when i open the modal it's fullscreen and when i swipe down to remove it, it disappear without stoping in the middle. So i would have only one gesture to remove it.


Solution

  • I think you can get this behavior with skipHalfExpanded property:

    val bottomSheetState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Expanded, skipHalfExpanded = true)