Graceful Exits: Implementing Close Confirmation for Jetpack Compose ModalBottomSheet | by Katie Barnett | Jan, 2024
The ModalBottomSheet in Jetpack Compose is easy to use, it just pops up at the bottom of the screen and allows the user easy interaction without covering the whole screen and blocking content.
The problem is, when the user accidentally taps out of the sheet or closes it they may lose any input they have added or changes they have made.
If we were using a custom close button then it would be easy, simply show a dialog when the user presses the button and only perform the sheet hide when the user has confirmed. But what about the bottom sheet handle, swiping down the bottom sheet or tapping outside on the scrim?
Fear not! It is pretty straight forward.
First, we have the basic building blocks of our
Here we have a simple
Boolean state to hold whether the
ModalBottomSheet should be displayed or not,
ModalBottomSheet also takes in
addSheetState which is initialised & tracked with
We also need to create a
AlertDialog to be the confirmation dialog to show when the user tries to close the
Both the dialog and the save button in the
ModalBottomSheet includes the closing of the
ModalBottomSheet using the
addSheetState.hide() method to allow the hide animation to run before fully removing the sheet from the composition via the
Observe the value change
Now we have the basic components the next thing to do is look at the
rememberModalBottomSheetState. This takes in a callback
confirmValueChange which we can confirm or veto a pending sheet state change. The change here is simple, we need to check if the requested sheet value is
Hidden (the other values are
PartiallyExpanded — we don’t care about these when showing the confirmation dialog) and if so, show the dialog. Then we need to return a
Boolean to indicate whether the sheet should take the requested action or not.
So, since we want to show the
AlertDialog we just set the
showConfirmChanges state to
true and return
false from the
confirmValueChange callback to prevent the action being carried out. If the requested sheet state value is not
Hidden then just return
true so it is carried out unaffected.
This will be run whenever the user touches outside of the
ModalBottomSheet or tries to swipe down on it using the handle. It won’t get called if a standard back press is used (as that is handled by the navigation architecture) but that can be overridden in a similar manner using
And that’s it! Simple!
Finally, we have the full solution:
- Mobile App Development (625)