Implementing Snackbar to undo actions in Jetpack Compose
When developing an app, we need to carefully focus on the user experience, specially in the actions that may require a confirmation or possibility to revert the user decision. If we use AlertDialog
in every single interaction we need this behavior, it will easily annoy the user.
One way of solving this issue is using a component available in the Material Design, the Snackbars. It inform users about a process your app has performed or will perform without interrupting the user experience. The component also allows users to amend their choices.

First steps with Snackbars
There is an implementation of Snackbar in Jetpack Compose already available. A code example for showing a message after a button click is:
In the code above we could notice two important components: SnackbarHost
and SnackbarHostState
. Using these two together allows the Snackbar to be properly shown, hidden and dismissed based on the Material Design guidelines. It also create a queue, once only one snackbar may be displayed at a time.
The Undo Snackbar
Let’s start our more complex example: implementing a Snackbar to undo a user action. First of all, we need to display a list of tasks from a ViewModel
and observe its changes over time. This is a simplified code for it:
Our Composable receives a ViewModel
that loads the task list (viewModel.taskList
) and calls a function to update the check status (viewModel.onCheckedChange
). Also, now it uses a Scaffold for better follow the Material Design layout structure (and soon we will see how it smoothly connects with our Snackbar 😊).
The current result is the following:

Our application has a business rule where only the tasks not yet completed should be displayed in the screen. Therefore as soon as the user clicks on our checkbox, the task is removed from the list. In our example, the ViewModel
is responsible for this logic.
Now, let’s implement the Snackbar, allowing the user to revert this action. The first step is creating the lambda function to be called with our Snackbar when the user clicks on the checkbox.
There is a lot of things going on in the code above, so let’s analyze it step by step:
- The line #3 in our functions is to remember the
CoroutineScope
, which is needed to show the snackbar, that is a suspend function. The line #4 is to remember theScaffoldState
, which contains theSnackbarHostState
already setup. - On line #6 we start our lambda function to be called when the user clicks on the checkbox. It receives the clicked task as parameter and returns nothing.
- On #8 we are calling the suspend function
showSnackbar()
with a message and the action label, and using the saving theSnackbarResult
to handle the different states. The line #12~15 handles the two possible results:Dismissed
andActionPerformed
. If the users clicked on the action button, we call theViewModel
to flip the boolean again. When the boolean isfalse
again, it will return to the list.
Now we can to associate our Snackbar with out Scaffold
and call our lambda in the onCheckedChange
parameter:
Once the ScaffoldState
already have a SnackbarHostState
which we used earlier, at this moment we simply pass it via parameters. And now we have the result we want. 😊

One more thing
During the development, I had some issues where the Snackbar disappeared right after showing up when the the user clicked on the checkbox. Just for a change, I asked on Kotlinlang Slack and Adam Powell helped me again. 🙂
The issue was that “the message will be removed from the queue if the call to showSnackbar
is cancelled”. Basically, I was declaring my rememberCoroutineScope
inside the function that composes the task item (fun ListItem
). Moving it to before the Scaffold
fixed the issue.
What’s next?
The complete code used for this article can be found at this Gist. Please, do not pay too much attention on the ViewModel
once I created a very naive implementation to simulate a data flow. In a real world application, this data would come from a Flow
linked to Room, for example.
If you want to see this implementation in a complex app, please access the Pull Request created to add this functionality to my personal app.
I hope that this simple implementation can help you creating your own Snackbar to undo users actions. Thanks a lot for reading my article and thanks Adam Powell for the coroutines tip! ❤️