Flutter ModalBottomSheet for beginners
According to Material Design Guide, the bottom sheet is a widget designed for displaying additional content that’s anchored to the bottom of the screen. Although it’s good to know the design rules to use this, that’s not the goal of this article. For more details about the design principles of BottomSheet go to Sheets: bottom — Material Design.
Now that you know about BottomSheet’s, you may be asking yourself: what is a ModalBottomSheet? How do we use them in Flutter?
Well, first questions first, there are two kinds of BottomSheets: modal and persistent. The persistent remains visible while the user interacts with the screen. The GoogleMaps app is an example of this.
On the other hand, the modal ones prevent users from doing other actions in the app. You could use them to confirm some operation, or request additional data, like asking the user how much exchange he will need while he is making an order in e-commerce apps, etc.
In this article, we will show how to use it by creating a simple weight tracker app, where we can submit our weight and see our previous weights. We won’t enter the app details, instead, we will head directly to the ModalBottomSheet implementation.
To display it, you will need to call showModalBottomSheet
from a context that has a Scaffold
, otherwise, you will get an error. That said, let's start building our sheet.
The first thing you should know is ModalBottomSheets height default to half of the screen, and to change it it’s necessary to pass true
to the isScrollControlled
argument and return a widget that matches the size we are expecting so let's do this.
Now, we need to add something so our users can input their weight let’s add a TextInput
and give it a TextEditingController
(this way even if our sheet is closed unexpectedly when the user opens it again its value will still be there).
Seems nice, but now we have a problem. When the user taps our TextField
the keyboard goes above it, why? Well, that happens because our sheet doesn’t adjust its position when the keyboard is open, we could make our sheet bigger, but that wouldn’t solve our problem, since we still need to add a field where users can insert the date that they recorded the weight. So what’s the solution? It’s simple if the keyboard is opened we make our sheet go above it, we can achieve this by giving our Container
a margin of EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom
and we will get the following result:
It’s starting to look nice, but don’t you think it would be smooth if we add some radius to our sheet? Let’s do it by adding shape
property just like below.
Cool, now let’s do our widget to select a date. Usually, you would create a widget just to handle this logic and expose the selected values using a ValueChanged
function, but to illustrate a problem you may face in the future let’s create all logic inside the sheet itself.
It’s important to notice that I’ve added the selectedDate
variable inside our HomePage State
as you will be able to see on the repository link I let in the end. But now we have a problem, although we are updating the value of selectedDate
using setState
our OutlineButton
still shows the old value until we reopen our sheet like you can see below.
To fix this, we will need to pass our OutlinedButton
to a StatefulBuilder
(or you could create a new widget and expose the changes using a callback as I said before, btw this is the more correct approach).
And that’s the final version of our ModalBottomSheet
!