I want to show snackbar with a button onclick in Jetpack Compose
I tried this
Button(onClick = {
Snackbar(action = {}) {
Text("hello")
}
}
But AS said "@Composable invocations can only happen from the context of a @Composable function"
Shall you give me a nice program.
I wish it can run in Button.onclick()
You'll need two things: SnackbarHostState - which will manage the state of your Snackbar (you would usually get that from the ScaffoldState ) CoroutineScope - which will be responsible for showing your Snackbar.
Show or hide snackbar By clicking the floating button, a snackbar with the text button appeared.
This example demonstrates how do I use snackBar in android. Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.
A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.
You'll need two things:
SnackbarHostState
- which will manage the state of your Snackbar
(you would usually get that from the ScaffoldState
)CoroutineScope
- which will be responsible for showing
your Snackbar
@Composable
fun SnackbarDemo() {
val scaffoldState = rememberScaffoldState() // this contains the `SnackbarHostState`
val coroutineScope = rememberCoroutineScope()
Scaffold(
modifier = Modifier,
scaffoldState = scaffoldState // attaching `scaffoldState` to the `Scaffold`
) {
Button(
onClick = {
coroutineScope.launch { // using the `coroutineScope` to `launch` showing the snackbar
// taking the `snackbarHostState` from the attached `scaffoldState`
val snackbarResult = scaffoldState.snackbarHostState.showSnackbar(
message = "This is your message",
actionLabel = "Do something."
)
when (snackbarResult) {
Dismissed -> Log.d("SnackbarDemo", "Dismissed")
ActionPerformed -> Log.d("SnackbarDemo", "Snackbar's button clicked")
}
}
}
) {
Text(text = "A button that shows a Snackbar")
}
}
}
Building on Bartek's answer you can also use Compose's side-effects. Then you don't have to manage the CoroutineScope itself.
Since Composables
itself should be side-effect free, it is recommended to make use of Compose's Effect APIs
so that those side effects are executed in a predictable manner.
In your specific case you can use the LaunchedEffect API
to run suspend functions in the scope of a composable. The example code would look like the following:
@Composable
fun SnackbarDemo() {
val scaffoldState = rememberScaffoldState() // this contains the `SnackbarHostState`
val (showSnackBar, setShowSnackBar) = remember {
mutableStateOf(false)
}
if (showSnackBar) {
LaunchedEffect(scaffoldState.snackbarHostState) {
// Show snackbar using a coroutine, when the coroutine is cancelled the
// snackbar will automatically dismiss. This coroutine will cancel whenever
// `showSnackBar` is false, and only start when `showSnackBar` is true
// (due to the above if-check), or if `scaffoldState.snackbarHostState` changes.
val result = scaffoldState.snackbarHostState.showSnackbar(
message = "Error message",
actionLabel = "Retry message"
)
when (result) {
SnackbarResult.Dismissed -> {
setShowSnackBar(false)
}
SnackbarResult.ActionPerformed -> {
setShowSnackBar(false)
// perform action here
}
}
}
}
Scaffold(
modifier = Modifier,
scaffoldState = scaffoldState // attaching `scaffoldState` to the `Scaffold`
) {
Button(
onClick = {
setShowSnackBar(true)
}
) {
Text(text = "A button that shows a Snackbar")
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With