Reputation: 1842
I show a SnackBar inside Scaffold like this:
val scaffoldState = rememberScaffoldState()
LaunchedEffect(offerViewModel.onAddToCartError) {
offerViewModel.onAddToCartError = {
coroutineScope.launch {
scaffoldState.snackbarHostState.showSnackbar(
message = message
)
}
}
}
Scaffold(
Modifier.nestedScroll(nestedScrollConnection),
scaffoldState = scaffoldState,
snackbarHost = {
SnackbarHost(it) { data ->
ErrorSnackBar(
message = data.message,
fontSize = 16.sp
)
}
}) { paddingValues ->
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
) {
//content
// full screen ModalBottomSheet
if (showBottomSheet) {
ModalBottomSheet(
modifier = modifier,
windowInsets = WindowInsets(
bottom = bottomInsets.getBottom(density).pxToDp().dp,
top = topInsets.getTop(density).pxToDp().dp
)
){...}
}
}
}
but if the ModalBottomSheet is shown, it covers my SnackBar. How can I show the SnackBar over all content including bottom sheets on my screen?
Upvotes: 4
Views: 2347
Reputation: 2394
Using a Popup
to show anything on top of a ModalBottomSheet
didn't work for me. Compose's ModalBottomSheet
is displayed using a window on Android, so it's outside of the Compose-created view tree. To overlay anything on top of it, you need another window that is added after the bottom sheet is displayed. Compose's Dialog
is implemented as a window in Android, so you can use it for that purpose, making sure that it takes the whole screen if needed and it passes touch and focus events down to anything that's below it. Here's my code:
Dialog(
onDismissRequest = {},
properties = DialogProperties(
dismissOnClickOutside = false,
dismissOnBackPress = false,
usePlatformDefaultWidth = false
)
) {
(LocalView.current.parent as DialogWindowProvider).window.apply {
setDimAmount(0f)
addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
}
// your Composable here
}
My answer is based on a post that helped me tremendously to get it right after lots of googling.
Upvotes: 0
Reputation: 358
You can cover with Popup() to show it over Dialog or ModalBottomSheet.
This has not built-in support for avoiding the IME (software keyboard), you can follow https://stackoverflow.com/a/75512140/12693743 to make it fully work.
SnackbarHost(LocalSnackBarHostState.current) {
Popup(
alignment = Alignment.TopCenter,
onDismissRequest = {
it.dismiss()
}
) {
Box(
modifier = Modifier
.fillMaxSize()
.noRippleClickable {
it.dismiss()
},
contentAlignment = Alignment.TopCenter
) {
Snackbar() // your implementation of Snackbar
}
}
}
Upvotes: 4