Implicit Animations in Flutter: Getting Started
Learn how to make smooth-flowing and beautiful apps by adding implicit animations to your Flutter project’s buttons, containers and screen transitions. By Yogesh Choudhary.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Implicit Animations in Flutter: Getting Started
30 mins
- Getting Started
- Understanding the Starter Project
- Animations in Flutter
- Seeing an Animation in Slow Motion
- Explicit and Implicit Animations
- Animating Buttons
- Making a Responsive TextField
- Using the Cross-fade Effect Between Widgets
- Animating Page Transitions
- Creating a Radial Menu
- Adding AnimatedSwitcher to Your Radial Menu
- Creating the Radial Menu Widget
- Adding AnimatedPositioned to the Radial Menu
- Implementing a Circular Progress Bar
- Where to Go From Here?
Adding AnimatedPositioned to the Radial Menu
Your Radial Menu is looking pretty good, but it needs an animation to match the rest of the application. To animate the menu buttons appearing, you're going to use the AnimatedPositioned
widget.
AnimatedPositioned
is the animated version of the Positioned
widget. Use this widget to change the position and size of the widget. Here are a couple points to keep in mind while working with this widget:
- It'll only work if its parent widget is
Stack
. - Although it's very useful,
AnimatedPositioned
is expensive, since it triggers a re-layout on every frame.
Navigate back to the radial_button file and replace the Positioned
widget at the top of Build
with an AnimatedPositioned
widget. Then, add two new arguments to the new AnimatedPositioned
:
duration: const Duration(milliseconds: 500),
curve: Curves.elasticIn,
The duration
argument sets the duration for the animation.
The curve
argument is more interesting. You can make your animation more realistic by adjusting its rate of change over time. This is where Curves
comes in handy in Flutter.
That's it, you've finally implemented this complex animation! Save the project and build and run:
Implementing a Circular Progress Bar
As mentioned earlier, you may come across a situation where you want to develop a basic animation, but Flutter doesn't have the animated version of that property or widget. In these situations, try the custom implicit animation builder TweenAnimationBuilder
. As you'll see, you don't need to call setState
for this animation widget, unlike the other implicit animation widgets.
You'll use the following animation widget to create a circular progress bar in the app. Open statistics_widget.dart in widgets. Add the following method to StatisticsWidgetState
:
Widget _tweenBuilder({
double endValue,
String statsName,
Color color,
double textSize,
}) {
return TweenAnimationBuilder(
// 1
tween: Tween(begin: 0.0, end: endValue),
// 2
duration: const Duration(milliseconds: 1500),
// 3
curve: Curves.easeOutBack,
// 4
child: _labelWidget(statsName, textSize),
// 5
builder: (
context,
value,
child,
) {
return _circularProgressBar(
color: color,
value: value,
labelWidget: child);
},
);
}
Here's an explanation of the numbered comments:
- The code passes a
Tween
object.Tween
is a linear interpolation between the beginning value and the end value. You then pass these interpolated values to the property of the soon-to-be-animated widget. - The code defines the duration of the widget's animation.
-
Curves.easeOutBlack
varies the rate of animation over the duration. - In
TweenAnimationBuilder
, you can pass a widget in thechild
parameter that doesn't depend on the animation and is a child of the animated widget. This is a good practice since the child widget only builds once, unlike the animated widget, and results in better perfomance.
Before moving further, here are a few points that will be helpful while working with TweenAnimationBuilder
:
- You can trigger the animation any time in
TweenAnimationBuilder
by providing a newTween.end
value. - The new animation triggered by changing the value of
Tween.end
runs from the animation value at that moment to the new end value.
While still in StatisticsWidgetState
, go to build
and find the //TODO: tweenBuilder
comment.
Delete this code:
_circularProgressBar(
value: 0.4,
color: Colors.blue,
labelWidget: _labelWidget('Stationery Purchased', _textSize)),
_circularProgressBar(
value: 0.3,
color: Colors.green,
labelWidget: _labelWidget('Planting Goal', _textSize)),
Replace the previous code with the following:
_tweenBuilder(
statsName: 'Stationery Purchased',
endValue: PlantStationeryConvertor.plantFraction,
color: Colors.blue,
textSize: _textSize),
_tweenBuilder(
statsName: 'Planting Goal',
endValue: PlantStationeryConvertor
.plantingStatus.getPlantationGoal / 10,
color: Colors.green,
textSize: _textSize),
That's it. Save the project, and build and run to review all the things that you accomplished today! :]
Where to Go From Here?
You can download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.
There are a few implicit animations that aren't covered in this tutorial. You can find them in Common implicitly animated widgets. Try adding more features into the app or replace used animation widgets with their alternatives, if possible.
Now is an ideal time to learn about the 12 Principles of Animations by the Disney animators Ollie Johnston and Frank Thomas. This will enable you to create more realistic and appealing animations in the future.
Also, check out the implicit animations video tutorial to get even more animation goodness in your life!
We hope you liked this tutorial. If you want more articles like this or have any questions, let us know by using the comments section below!