Not all animations are complex
Many have expressed interest in how to make amazing animations that can mesmerize users, yet still have the unbelievable performance Flutter has become known for. Yes, you can! You can not only make jaw-dropping animations with more customized transformations, you can also get great results by taking the first baby steps and using what’s already available in the Flutter SDK. The Flutter team worked really hard to make it easy with “implicit animations”.
In this post, we‘ll take a look at AnimatedContainer.
If you want to dig a lot deeper into it, I’d definitely recommend this post from Pooja Bhaumik where she explains this widget in depth.
Our Homework for today:
When we break this down into components, we see this UI could be made up of things like:
- Stack
- A couple of buttons on the top
- An image in the background
- Text (date and name)
- And what’s that at the bottom? Is it a
bottomSheet,
or maybe, just maybe, it’s anAnimatedContainer
.
That's what I can see at first glance, but you know this will need a little more than that. We’re going to use some Rows
, Columns
, Containers
(regular and animated) plus an InkWell.
We need the InkWell
because we’re going to need something to Tap in order to change our AnimatedContainer
values and let the magic inside Flutter flow!
Let's write some code!
First, we’re going to be working with a statefulWidget
that returns a Scaffold,
with a Stack
in for its body:
Not much to explain there, let’s keep going!
Wait, is that duplicate code I see? Oh no, that’s got to go. We need to change that before someone sees it and starts thinking we’re coding in the stone age… and my boss cuts me off from the coffee machine.
Now that that’s fixed, where were we? Ah yes… We start off with a Stack
that has a Container
in its first layer. Our Container
has an Image
background, and we use BoxFit.cover
to be sure the Image
will completely cover the Container
. In the second layer, we have a Column
and we’ll use the default MainAxisSize.max
so it takes up all the space it can get in the MainAxis.
The rest of this is actually pretty easy. We’ll use a Container
with some Padding
and, inside of it, we’ll put a Row
with a pair of buttons. We’ll set the Row’s
mainAxisAligment
property to MainAxisAlignment.spaceBetween
, and this will finish up the back and upper parts of our UI.
So, have you noticed we didn’t say anything about anAnimationController
or SingleTickerProviderStateMixin?
Now, if neither of those names rings a bell, you’re in the right place.
The final step is to make that little bottom, white, pill-looking thing go up until it’s almost full-screen, or back down, when onTap is triggered. Let’s get into it!
I’m going to “code and explain later”; so you’ll have a chance to read it, process it, and hopefully learn from it.
There isn’t a lot that got added for the animation:
- The
Positioned
Widget can be used inside theStack
to set the position of our “little white pill”. We just set the bottom property to 0, causing the pill to align with the bottom of the screen. - Add
bool
variable, called “open”, to know the state of the "pill", and then initialize it to false. - Two more variables,
minHeight
andmaxHeight,
are going to be the ones controlling the height of ourAnimatedContainer
in order to create our animation. To do this, we calculate 10% and 85% of the screen height by using theMediaQuery.of(context).size.height
- Now we can add the
AnimatedContainer,
taking advantage of its power and the functionality of the implicit animation it provides. Don't forget that to set a duration, you need it for this Widget to work. - Finally, we add the
Container
(the “pill”) and wrap it with anInkWell
so we can change the value of ouropen
variable.
You will find more code in there than what I’ve described above, but I think the rest is pretty self-explanatory. There’s some Text, Padding
and a BorderRadius
but I’ll leave you to play with those.
And just like that, we have a small but usable animation that didn’t take much effort at all. This is kind of a basic design for a UI Animation, but that was actually my goal for this post. If you only recently started flirting with Flutter this could help you to start going deeper and deeper.
This code leaves a lot of room for improvement. You could start with an Animation Controller in order to have more control, but you need to remember that you need to use the proper mixin for this to work. You could absolutely use other Widgets like a GestureDetector,
too.
Play with the settings for the Container
and see how that changes the way it behaves when you drag it! That’s the beauty of coding, you can try different approaches and still get the same UI but with a lot better (or worse) performance. Never forget performance, and another important part is your app UX. Remember, smooth performance can be the difference between a great User Experience and an uninstalled app!
You can follow the author here: