SnackbarHostState
-
Cmn
class SnackbarHostState
State of the SnackbarHost
, which controls the queue and the current Snackbar
being shown inside the SnackbarHost
.
This state is usually remember
ed and used to provide a SnackbarHost
to a Scaffold
.
Summary
Public constructors |
|
---|---|
Cmn
|
Public functions |
||
---|---|---|
suspend SnackbarResult |
showSnackbar(visuals: SnackbarVisuals) Shows or queues to be shown a |
Cmn
|
suspend SnackbarResult |
showSnackbar( Shows or queues to be shown a |
Cmn
|
Public properties |
||
---|---|---|
SnackbarData? |
The current |
Cmn
|
Public constructors
Public functions
showSnackbar
suspend fun showSnackbar(visuals: SnackbarVisuals): SnackbarResult
Shows or queues to be shown a Snackbar
at the bottom of the Scaffold
to which this state is attached and suspends until the snackbar has disappeared.
SnackbarHostState
guarantees to show at most one snackbar at a time. If this function is called while another snackbar is already visible, it will be suspended until this snackbar is shown and subsequently addressed. If the caller is cancelled, the snackbar will be removed from display and/or the queue to be displayed.
All of this allows for granular control over the snackbar queue from within:
import androidx.compose.foundation.border import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExtendedFloatingActionButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Snackbar import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarVisuals import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp 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() ) } )
Parameters | |
---|---|
visuals: SnackbarVisuals |
|
Returns | |
---|---|
SnackbarResult |
|
showSnackbar
suspend fun showSnackbar(
message: String,
actionLabel: String? = null,
withDismissAction: Boolean = false,
duration: SnackbarDuration = if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite
): SnackbarResult
Shows or queues to be shown a Snackbar
at the bottom of the Scaffold
to which this state is attached and suspends until the snackbar has disappeared.
SnackbarHostState
guarantees to show at most one snackbar at a time. If this function is called while another snackbar is already visible, it will be suspended until this snackbar is shown and subsequently addressed. If the caller is cancelled, the snackbar will be removed from display and/or the queue to be displayed.
All of this allows for granular control over the snackbar queue from within:
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.ExtendedFloatingActionButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Snackbar import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier // decouple snackbar host state from scaffold state for demo purposes // this state, channel and flow is for demo purposes to demonstrate business logic layer val snackbarHostState = remember { SnackbarHostState() } // we allow only one snackbar to be in the queue here, hence conflated val channel = remember { Channel<Int>(Channel.CONFLATED) } LaunchedEffect(channel) { channel.receiveAsFlow().collect { index -> val result = snackbarHostState.showSnackbar( message = "Snackbar # $index", actionLabel = "Action on $index" ) when (result) { SnackbarResult.ActionPerformed -> { /* action has been performed */ } SnackbarResult.Dismissed -> { /* dismissed, no action needed */ } } } } Scaffold( snackbarHost = { SnackbarHost(snackbarHostState) }, floatingActionButton = { var clickCount by remember { mutableStateOf(0) } ExtendedFloatingActionButton( onClick = { // offset snackbar data to the business logic channel.trySend(++clickCount) } ) { Text("Show snackbar") } }, content = { innerPadding -> Text( "Snackbar demo", modifier = Modifier.padding(innerPadding).fillMaxSize().wrapContentSize() ) } )
To change the Snackbar appearance, change it in 'snackbarHost' on the Scaffold
.
Parameters | |
---|---|
message: String |
text to be shown in the Snackbar |
actionLabel: String? = null |
optional action label to show as button in the Snackbar |
withDismissAction: Boolean = false |
a boolean to show a dismiss action in the Snackbar. This is recommended to be set to true for better accessibility when a Snackbar is set with a |
duration: SnackbarDuration = if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite |
duration to control how long snackbar will be shown in |
Returns | |
---|---|
SnackbarResult |
|
Public properties
currentSnackbarData
val currentSnackbarData: SnackbarData?
The current SnackbarData
being shown by the SnackbarHost
, or null
if none.