SnackbarHost
Composable Component
Host for Snackbar
s to be used in Scaffold
to properly show, hide and dismiss items based on
Material specification and the hostState
.
Common
@Composable
fun SnackbarHost(
hostState: SnackbarHostState,
modifier: Modifier = Modifier,
snackbar: @Composable (SnackbarData) -> Unit = { Snackbar(it) },
)
Parameters
hostState | state of this component to read and show Snackbar s accordingly |
modifier | the Modifier to be applied to this component |
snackbar | the instance of the Snackbar to be shown at the appropriate time with appearance based on the SnackbarData provided as a param |
Code Examples
ScaffoldWithSimpleSnackbar
@Preview
@Composable
fun ScaffoldWithSimpleSnackbar() {
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
snackbarHost = { SnackbarHost(snackbarHostState) },
floatingActionButton = {
var clickCount by remember { mutableStateOf(0) }
ExtendedFloatingActionButton(
onClick = {
// show snackbar as a suspend function
scope.launch { snackbarHostState.showSnackbar("Snackbar # ${++clickCount}") }
}
) {
Text("Show snackbar")
}
},
content = { innerPadding ->
Text(
text = "Body content",
modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize(),
)
},
)
}
ScaffoldWithCustomSnackbar
@Preview
@Composable
fun ScaffoldWithCustomSnackbar() {
class SnackbarVisualsWithError(override val message: String, val isError: Boolean) :
SnackbarVisuals {
override val actionLabel: String
get() = if (isError) "Error" else "OK"
override val withDismissAction: Boolean
get() = false
override val duration: SnackbarDuration
get() = SnackbarDuration.Indefinite
}
val snackbarHostState = remember { SnackbarHostState() }
val scope = rememberCoroutineScope()
Scaffold(
snackbarHost = {
// reuse default SnackbarHost to have default animation and timing handling
SnackbarHost(snackbarHostState) { data ->
// custom snackbar with the custom action button color and border
val isError = (data.visuals as? SnackbarVisualsWithError)?.isError ?: false
val buttonColor =
if (isError) {
ButtonDefaults.textButtonColors(
containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.error,
)
} else {
ButtonDefaults.textButtonColors(
contentColor = MaterialTheme.colorScheme.inversePrimary
)
}
Snackbar(
modifier =
Modifier.border(2.dp, MaterialTheme.colorScheme.secondary).padding(12.dp),
action = {
TextButton(
onClick = { if (isError) data.dismiss() else data.performAction() },
colors = buttonColor,
) {
Text(data.visuals.actionLabel ?: "")
}
},
) {
Text(data.visuals.message)
}
}
},
floatingActionButton = {
var clickCount by remember { mutableStateOf(0) }
ExtendedFloatingActionButton(
onClick = {
scope.launch {
snackbarHostState.showSnackbar(
SnackbarVisualsWithError(
"Snackbar # ${++clickCount}",
isError = clickCount % 2 != 0,
)
)
}
}
) {
Text("Show snackbar")
}
},
content = { innerPadding ->
Text(
text = "Custom Snackbar Demo",
modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize(),
)
},
)
}
Create your own Component Library
Material Components are meant to be used as is and they do not allow customizations. To build your own Jetpack Compose component library use Compose Unstyled