Sheet State¶
FlexibleBottomSheetState¶
FlexibleBottomSheetState is a crucial concept that must be bound to FlexibleBottomSheet to manage its state changes. It also enables you to customize UI/UX behaviors for the bottom sheet and take manual control over expanding/hiding the bottom sheet.
You can remember the FlexibleBottomSheetState by using rememberFlexibleBottomSheetState:
FlexibleBottomSheet(
onDismissRequest = onDismissRequest,
sheetState = rememberFlexibleBottomSheetState(
skipSlightlyExpanded = false,
skipIntermediatelyExpanded = false,
isModal = true,
allowNestedScroll = true,
flexibleSheetSize = FlexibleSheetSize(
fullyExpanded = 1.0f,
intermediatelyExpanded = 0.5f,
slightlyExpanded = 0.25f
)
),
) {
// content
}
Expanded States¶
The flexible bottom sheet offers four primary sheet states known as FlexibleSheetValue:
| State | Description |
|---|---|
| Fully Expanded | The sheet is visible at its fully-expanded height. This is mandatory and cannot be skipped. |
| Intermediately Expanded | The sheet is visible at an intermediate expanded height. Can be skipped by setting skipIntermediatelyExpanded to true. |
| Slightly Expanded | The sheet is visible at a slightly expanded height. Skipped by default, enable by setting skipSlightlyExpanded to false. |
| Hidden | The sheet is completely not visible on the screen. To keep the sheet always visible, set skipHiddenState to true. |
Skipping States¶
You can skip the Intermediately Expanded and Slightly Expanded states:
FlexibleBottomSheet(
onDismissRequest = onDismissRequest,
sheetState = rememberFlexibleBottomSheetState(
skipSlightlyExpanded = false, // Enable slightly expanded
skipIntermediatelyExpanded = false // Enable intermediately expanded
),
) {
// content
}
Initial Value¶
You can specify the initial expanded state when the bottom sheet first appears by using the initialValue parameter. This allows you to start the sheet at a specific state without animation:
FlexibleBottomSheet(
onDismissRequest = onDismissRequest,
sheetState = rememberFlexibleBottomSheetState(
initialValue = FlexibleSheetValue.FullyExpanded,
skipSlightlyExpanded = false,
),
) {
// content
}
Available initial values:
FlexibleSheetValue.Hidden(default)FlexibleSheetValue.SlightlyExpandedFlexibleSheetValue.IntermediatelyExpandedFlexibleSheetValue.FullyExpanded
Compatibility with Skip Settings
The initialValue must be compatible with the skip settings. For example:
- If
skipSlightlyExpanded = true, you cannot setinitialValue = FlexibleSheetValue.SlightlyExpanded - If
skipIntermediatelyExpanded = true, you cannot setinitialValue = FlexibleSheetValue.IntermediatelyExpanded
Manual Control¶
You can expand or hide the bottom sheet manually by utilizing the FlexibleBottomSheetState:

val scope = rememberCoroutineScope()
val sheetState = rememberFlexibleBottomSheetState(
flexibleSheetSize = FlexibleSheetSize(fullyExpanded = 0.9f),
isModal = true,
skipSlightlyExpanded = false,
)
FlexibleBottomSheet(
sheetState = sheetState,
containerColor = Color.Black,
onDismissRequest = onDismissRequest
) {
Button(
modifier = Modifier.align(Alignment.CenterHorizontally),
onClick = {
scope.launch {
when (sheetState.swipeableState.currentValue) {
FlexibleSheetValue.SlightlyExpanded ->
sheetState.intermediatelyExpand()
FlexibleSheetValue.IntermediatelyExpanded ->
sheetState.fullyExpand()
else -> sheetState.hide()
}
}
},
) {
Text(text = "Expand Or Hide")
}
}
Available Methods¶
| Method | Description |
|---|---|
show() |
Shows the bottom sheet |
hide() |
Hides the bottom sheet |
fullyExpand() |
Expands to fully expanded state |
intermediatelyExpand() |
Expands to intermediately expanded state |
slightlyExpand() |
Expands to slightly expanded state |
Monitoring State Changes¶
You can dynamically compose your bottom sheet content by tracking the bottom sheet state changes using the onTargetChanges callback:

var currentSheetTarget by remember {
mutableStateOf(FlexibleSheetValue.IntermediatelyExpanded)
}
FlexibleBottomSheet(
onDismissRequest = onDismissRequest,
sheetState = rememberFlexibleBottomSheetState(
skipSlightlyExpanded = false
),
onTargetChanges = { sheetValue ->
currentSheetTarget = sheetValue
},
containerColor = Color.Black,
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
text = "This is Flexible Bottom Sheet",
textAlign = TextAlign.Center,
color = Color.White,
fontSize = when (currentSheetTarget) {
FlexibleSheetValue.FullyExpanded -> 28.sp
FlexibleSheetValue.IntermediatelyExpanded -> 20.sp
else -> 12.sp
},
)
}