Jonas
Jonas

Reputation: 287

Expand navigation material ModalBottomSheetLayout to max or custom height

I'm trying to implement https://google.github.io/accompanist/navigation-material/ and i want to expand modelsheet to custom height or more than half screen but i don't have any idea how to achieve it

Currently ModelBottomSheet

enter image description here

Wish to expand like this

enter image description here

Upvotes: 4

Views: 4653

Answers (1)

Huib
Huib

Reputation: 344

Instead of using the show method of the ModalBottomSheetState, You can use the animateTo method. The show method will default to a half screen size modal. The animateTo(ModalBottomSheetValue.Expanded) will expand to the full size of the content. In the example i've used a BoxWithConstrains to get the screen size and set the size of the modal content to 80%.

I hope this helps!

@Composable
@Preview
fun BottomSheetDemo() {
    val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)

    BoxWithConstraints {
        val sheetHeight = this.constraints.maxHeight * 0.8f
        val coroutineScope = rememberCoroutineScope()
        Column {
            Button(onClick = {
                coroutineScope.launch { modalBottomSheetState.animateTo(ModalBottomSheetValue.Expanded) }
            }) {
                Text(text = "Expand")
            }
            Button(onClick = {
                coroutineScope.launch { modalBottomSheetState.animateTo(ModalBottomSheetValue.Hidden) }
            }) {
                Text(text = "Collapse")
            }
        }
        ModalBottomSheetLayout(
            sheetBackgroundColor = Color.Red,
            sheetState = modalBottomSheetState,
            sheetContent = {
                Box(modifier = Modifier.height(with(LocalDensity.current) { sheetHeight.toDp() })) {
                    Text(text = "This is some content")
                }
            }
        ) {}
    }
}

EDIT:

If you want to use the material navigation, you will need a custom extension function. The difference in this function with the original is the skipHalfExpanded parameter. This on will make it possible to create bottom sheets larger then half screen.

@Composable
fun rememberBottomSheetNavigator(
    animationSpec: AnimationSpec<Float> = SwipeableDefaults.AnimationSpec
): BottomSheetNavigator {
    val sheetState = rememberModalBottomSheetState(
        initialValue = ModalBottomSheetValue.Hidden,
        animationSpec = animationSpec,
        skipHalfExpanded = true
    )
    return remember(sheetState) {
        BottomSheetNavigator(sheetState = sheetState)
    }
}

The implementation itself will be something like this:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            val bottomSheetNavigator = rememberBottomSheetNavigator()
            val navController = rememberNavController(bottomSheetNavigator)
            ModalBottomSheetLayout(bottomSheetNavigator) {
                NavHost(navController, "home") {
                    composable(route = "home") {
                        Home(navController)
                    }
                    bottomSheet(route = "sheet") {
                        ModalDemo()
                    }
                }
            }
        }
    }
}

@Composable
fun Home(navController: NavController) {
    val coroutineScope = rememberCoroutineScope()
    Column {
        Button(onClick = {
            coroutineScope.launch { navController.navigate("sheet") }
        }) {
            Text(text = "Expand")
        }
    }
}

@Composable
fun ModalDemo() {
    Column(Modifier.fillMaxWidth().height(700.dp).background(Color.Red), horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "This is some content")
    }
}

Upvotes: 9

Related Questions