7

Implementing Snackbar to undo actions in Jetpack Compose

 3 years ago
source link: https://proandroiddev.com/implementing-snackbar-to-undo-actions-in-jetpack-compose-7b8ec92cf8a7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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.

Source: Material Design — Snackbars

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:

1*jcNRuzGeMeEsEP-E0BnB-A.png?q=20
implementing-snackbar-to-undo-actions-in-jetpack-compose-7b8ec92cf8a7

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 the ScaffoldState, which contains the SnackbarHostState 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 the SnackbarResult to handle the different states. The line #12~15 handles the two possible results: Dismissed and ActionPerformed. If the users clicked on the action button, we call the ViewModel to flip the boolean again. When the boolean is false 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. 😊

1*uaJ_ixXEzklW3kArq-W57g.gif?q=20
implementing-snackbar-to-undo-actions-in-jetpack-compose-7b8ec92cf8a7

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

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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK