介绍
下面的代码是使用 Snackbar 的常用方式(和 Scaffold 一起使用),使用 ScaffoldState 提供的 SnackbarHost 来显示 Snackbar,它有默认的 Snackbar 显示位置,并且会处理页面中有 FloatingActionButton 时 Snackbar 的显示位置。
@Composable
fun MainScreen() {
val scaffoldState = rememberScaffoldState()
val coroutineScope = rememberCoroutineScope()
Scaffold(scaffoldState = scaffoldState) {
Button(onClick = {
coroutineScope.launch {
scaffoldState.snackbarHostState.showSnackbar("Button Clicked")
}
}) {
Text("Click to show Snackbar")
}
}
}
但是有时可能也会遇到需要在没有 Scaffold/脚手架 的布局中使用 Snackbar。
例如,想要在 ModalBottomSheetLayout 中使用 Snackbar 时,ModalBottomSheet 没有 SnackbarHost 参数,不能轻松的和 Scaffold 整合到一起使用。
这种情况不使用 Scaffold,定义我们自己的 SnackbarHostState 即可。
不通过 Scaffold 使用 Snackbar
@Composable
private fun SnackbarWithoutScaffold() {
Box(Modifier.fillMaxSize()) {
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()
Button(onClick = {
coroutineScope.launch {
snackbarHostState.showSnackbar("Button Clicked")
}
}) {
Text("Click to show Snackbar")
}
SnackbarHost(
modifier = Modifier
.align(Alignment.BottomCenter)
.windowInsetsPadding(WindowInsets.safeDrawing),
hostState = snackbarHostState,
)
}
}

在 ModalBottomSheetLayout 中使用 Snackbar
@OptIn(ExperimentalMaterialApi::class)
@Composable
private fun ModalBottomSheetWithSnackbar() {
val bottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden)
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()
Box(Modifier.fillMaxSize()) {
Button(
onClick = {
coroutineScope.launch {
bottomSheetState.show()
}
},
) {
Text("Click to show ModalBottomSheet")
}
ModalBottomSheetLayout(
sheetState = bottomSheetState,
sheetContent = {
Button(
modifier = Modifier.padding(horizontal = 16.dp, vertical = 70.dp),
onClick = {
coroutineScope.launch {
snackbarHostState.showSnackbar("Button Clicked")
}
},
) {
Text("Click to show Snackbar")
}
},
) {
Text(text = "ModalBottomSheet with Snackbar")
}
SnackbarHost(
modifier = Modifier
.align(Alignment.BottomCenter)
.windowInsetsPadding(WindowInsets.safeDrawing),
hostState = snackbarHostState,
)
}
}
