Flutter Animation
Flutter Animation
Animations are an important aspect of making a mobile app’s user interface feel natural and fluid. An app’s usability is enhanced by smooth transitions and interactive elements. Poorly designed animations, on the other hand, might make the app look awkward or, worse, cause it to crash. As a result, understanding the principles of animations in any framework is critical to providing a great user experience.
Creating a simple Flutter animation
Here is what we will create as our first Flutter animation:

At the center, there is a Container widget that has two simultaneous animations: a color change and size change.
Creating a project
To create a project, go to File -> New -> Flutter project and select Flutter application.

Leave everything else to default and click finish.
Basic Code setup
Let’s delete the code from main.dart and paste our starter code shown below:
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Animation Demo"),
),
);
}
}
This gives you just a blank screen with an AppBar.
Setting up AnimationControllers and Animations
We need to define our animations and controller to control the animations.
Before we do this, we need to add a mixin to our class for vsync for the AnimationController.
class _MyHomePageState extends State<MyHomePage> with
SingleTickerProviderStateMixin {
//This mixin provides ‘ticks’ for the controller to change values over time.
//Finally, we set up our animation controller and animations as follows:
AnimationController controller;
Animation colorAnimation;
Animation sizeAnimation;
@override
void initState() {
super.initState();
controller = AnimationController(vsync: this, duration: Duration(seconds: 2));
colorAnimation = ColorTween(begin: Colors.blue, end: Colors.yellow).animate(controller);
sizeAnimation = Tween<double>(begin: 100.0, end: 200.0).animate(controller);
}
initState() is the first function that runs when building a widget. Here, we initialise our variables. For the controller, we pass in the vsync parameter, which is given by the SingleTickerProviderStateMixinwe added to the State class. We have also set the duration of the animation to 2 seconds.
Next, for this animation, we will be using Tweens we discussed earlier.
First, let’s create a Tween. For color, this is:
ColorTween(begin: Colors.blue, end: Colors.yellow)
This creates a tween which starts from blue and ends in yellow and will give us all colors in between. To create an animation out of it, we use the animate() method on it, passing in our AnimationController. We will do this for sizeAnimation animation as well, where we start with a size of 100.0 and end with 200.0.
Building the box
To create a box, we can use the Container() widget by setting height, width and color.
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Animation Demo"),
),
body: Center(
child: Container(
height: sizeAnimation.value,
width: sizeAnimation.value,
color: colorAnimation.value,
),
),
);
}
We can get the current value of the animation simply by {animationName}.value. We have also added the Center widget to center the box on the screen.
Starting the animation
To start an animation, we can use the controller we defined earlier as it controls all animations tied to it. The simplest way to do it is controller.forward() and to reverse, controller.reverse().
However, the controller also gives us other options like controller.repeat() which repeats the animation continuously and controller.fling() which flings (runs an animation quickly regardless of duration) the animation.
If you run the animation now, it will not work since we are not rebuilding the box when the animation values change.
Rebuilding the box on animation value change
As mentioned earlier, we use the setState() function to rebuild the box. The question, however, is when do we rebuild the box? Is it before, during or after the animation?
We want to rebuild the animation when the progression value changes (animation goes a step ahead). The AnimationController is responsible for keeping track of the progress of the animation. We can use it to know when the animation updates. To do this we will simply add a listener to the controller and rebuild on change.
// In initState
controller.addListener(() {
setState(() {});
});
And we’re done! Go ahead to experiment with various Tweens to create new kinds of Flutter animations.
Adding curves for a better look
In our animation, you would have noticed that linearly increasing the size or changing color doesn’t look very impressive to the user. To improve upon this, we can add curves to our animation. Curves change how the animation value changes over time, making it faster and slower over a duration leading to a better look.
To add a curve, simply add a CurvedAnimation instead of adding the controller while initialising the animation.
colorAnimation = ColorTween(begin: Colors.blue, end: Colors.yellow)
.animate(CurvedAnimation(parent: controller, curve: Curves.bounceOut));
This gives us a bouncy effect when the animation is ending:
