Bottomsheetdialog No Modalbottomsheetlayout No Scaffold And Its Scrim
Published:
Say you want to make a BottomSheetDialog that:
- Has no Scrim Layout
- Can do interaction behind it (its main layout)
- Just a simple one (visible and inVisible),
- As for implications there’s no need
modalBottomSheetState
just visible (expand) and hide (invisible)
Have a look at the codebase here, the ModalBottomSheetLayout()
part
You realize the ModalBottomSheetLayout
is using BoxConstraintLayout
Skip the Box()
and its Scrim()
one, they are the MainContent()
Just hop in to the Surface
that is the ModalBottomSheetContent()
from API
You can get them as a reference
The key is the offset{}
Modifier
Then you can use BoxConstraints(){constraints.maxHeight}
to get the layout fullHeight,
The default alignment is Top
, assuming maxHeight
takes a whole screen, then use the offset with y
using that value
If you want to get the content height, use the onGloballyPositioned{}
remember the height there
val sheetHeightState = remember { mutableStateOf(0) }
..
Modifier
.onGloballyPositioned {
sheetHeightState.value = it.size.height
}
Now you get the height of that layout, substract the maxHeight
with it.
Make use of the animateIntOffsetAsState()
to apply Modifier.offset{}
val currentHeight = animateIntOffsetAsState(targetValue = IntOffset(0, if(isVisible) maxHeight - sheetHeightState.value else maxHeight))
apply it to the Surface
@ExperimentalFoundationApi
@ExperimentalMaterialApi
@Composable
private fun CustomDialog(
isVisible: Boolean,
modifier : Modifier = Modifier,
) {
BoxWithConstraints(modifier) {
val fullHeight = constraints.maxHeight
val sheetHeightState = remember { mutableStateOf(0) }
val currentHeight = animateIntOffsetAsState(targetValue = IntOffset(0, if(isVisible) fullHeight - sheetHeightState.value else fullHeight))
Surface(
Modifier
.fillMaxWidth()
.offset {
currentHeight.value
}
.onGloballyPositioned {
sheetHeightState.value = it.size.height
},
shape = BottomDialogShape,
elevation = 0.dp,
color = Color.Transparent,
contentColor = Color.Transparent
) {
Column {
ModalBottomSheetContent()
}
}
}
}