Introduction to Flutter Animation Part 1
Tags: flutteranimation, flutterframework, flutterdevelopment
Published: 2021-05-12 06:17:20

Well-designed animations enhance the user experience by making a UI feel more natural. They also add to the slick look and feel of a polished app. Flutter's animation support allows a number of animation styles to be simple to introduce. Many widgets, especially Material widgets, have standard motion effects specified in their design spec, but these effects can also be customized.

Animation is a very important aspect and powerful concept in Flutter. When it comes to using or creating any mobile app, you cannot imagine any app without animation.

It changes the way you see things. Animation directly catches anyone’s attention. Follow the recommendations to add a lit bit of advanced animation to spice up the user experience of your mobile application.

“Animation is not the art of drawing that move but the art of movements that are drawn.” – Norman McLaren

Creating some astonishing animations for your mobile app is the base and the most important thing in any application.

Interesting Fact: Around 5,00,000 developers use Flutter monthly according to Google and with more than 2 million developers, flutter uptick in enterprise use. 

Flutter offers an exquisite support for animation where it separates the animation in two main categories, that are:

Tween Animation
Physics-Based Animation
Let’s get rolling with both type of animation.

#1 TWEEN ANIMATION
Tweening” is how flutter animators create all types of animation, including computer animation. This process generates and includes frames between two images. These frames, that come in between two images are called key Frames.

It’s the abbreviated version of in-betweening. In a tween animation, the start and endpoints of the animation must be specified. It means that the animation starts with the start value and progresses through a sequence of intermediate values before arriving at the end value. Moreover, it also includes a timeline and curve that describe the transition’s duration and pace.

It also offers an appearance where the first image evolves smoothly to the second image.

TWEENANIMATIONBUILDER
TweenAnimationBuilder is here for all your needs without having to worry about the pesky animation controller.

Moreover, using TweenAnimationBuilder is easy. Thus, you can set the duration of any particular animation to the time you want it to run.

eg.

1
2
3
TweenAnimationBuilder<Color>(
duration: const Duration(seconds:4),
)
Using this syntax, you can set the length of the time according to your preference with duration parameter and then add your builder method to draw the widget you’ll be animating.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class TweenAnimationExample extends StatefulWidget {
@override
_TweenAnimationExampleState createState() => _TweenAnimationExampleState();
}
class _TweenAnimationExampleState extends State<TweenAnimationExample> {
double zoomInOutValue = 48.0;
@override
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
tween: Tween<double>(begin: 0, end: zoomInOutValue),
duration: const Duration(seconds: 1),
builder: (BuildContext context, double size, Widget child) {
return IconButton(
iconSize: size,
color: Colors.blue,
icon: child,
onPressed: () {
setState(() {
zoomInOutValue = zoomInOutValue == 48.0 ? 96.0 : 48.0;
});
},
);
},
child: const Icon(Icons.ac_unit),
);
}
}
Output:

As you know, that the parameter type depends on what you’re animating.

The second parameter is dependent on what in your widget you’ll be animating. In this case, it holds the choice of Color value you wish to apply in the color filter.

At the end, specify the values that you want to animate between using the tween parameter

Note: The type of your tween should match the type of the second parameter in your builder and the Class type parameter, in case if you specify it.

Do this and there you go! You’ll get a working custom implicit animation.

TWEEN.ANIMATE
To use a Tween object, call animate() on it with the controller object as the argument. For example, over the course of 300 milliseconds, the following code generates integer values ranging from 0 to 200.

1
2
3
AnimationController controller = AnimationController(
duration: const Duration(milliseconds: 300), vsync: this);
Animation<int> alpha = IntTween(begin: 0, end: 200).animate(controller);
Note: The animate() will return an Animation, not an Animatable.

TRANSITION WITH CURVE PARAMETER
If you wish to modify the way you animate from one value to another, You can set curve parameter by using the following code

1
curve: Curve.bounceInOut,
Use the code in this way:

1
2
3
4
5
6
TweenAnimationBuilder<Color>(
    duration: const Duration(seconds:4),
    tween: ColorTween(
            begin: Color.white, end: Colors.pink),
curve: Curve.bounceInOut,
builder: (BuildContext _, Color value, Widget __) {...}
ANIMATION NOTIFICATION
In Animation Notification, Listeners and StatusListeners adds to an Animation object using the addListener() and addStatusListener() methods (). When the animation’s value increases, a Listener gets call. Although, the most popular action of Listener is to call setState() to force a rebuild. When an animation starts, ends, moves forward, or reverses, according to AnimationStatus, a StatusListener gets a name. Thus, the addListener() method is demonstrated in the next section, and an example of addStatusListener is demonstrated in the section Monitoring the progress of the animation.

#2 PHYSICS-BASED ANIMATION
Physics-based Animation is a form of animation that lets you create an app’s interaction feel more realistic and interactive. It simulates real-world movement/animation, such as dropping, springing, or swinging with gravity, etc. As a result, it’s an animation that reacts to user movement or input.

The simplest example is the length of a trip, and the distance travelled will be measured using physics rules.

App interactions is done in more realistic and interactive way with the use of physics Animation.

Let’s understand it more clearly using the GravitySimulation example.

GRAVITYSIMULATION
Initialized with acceleration, beginning point, ending point, and starting velocity, this class simulates gravity. In this example, 100 units of acceleration in this case, and our destination is zero to 500 with zero initial velocity.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
 
class GravityBasedAnimationExample extends StatefulWidget {
_GravityBasedAnimation createState() => _GravityBasedAnimation();
}
 
class _GravityBasedAnimation extends State<GravityBasedAnimationExample>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
GravitySimulation _gravitySimulation;
 
@override
void initState() {
super.initState();
_gravitySimulation = GravitySimulation(
100.0, // acceleration
0.0, // starting point
500.0, // end point
0.0, // starting velocity
);
_animationController = AnimationController(vsync: this, upperBound: 500)
..addListener(() {
setState(() {});
});
_animationController.animateWith(_gravitySimulation);
}
 
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Stack(children: [
Positioned(
left: 100,
top: _animationController.value,
height: 24.0,
width: 24.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.0),
color: Colors.blue,
),
),
),
]),
);
}
 
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}
Output:

upper bound: It could be a bug, or it could just be me. Since the AnimationController class value has a max and min limit, the simulation’s end location will not function as anticipated. Thus, the upper bound property’s default value is 1. If you’re using simulation and your controller. value is stuck at 1, you should adjust the upper-bound value.

control.animateWith: Thus, it tells the controller to use the simulation we set up in controller.animateWith. You’ll note that the period in the controller is not specified because the duration of the animation is calculated by the controller based on the parameters we set in our simulation.

SPRINGSIMULATION
Using a Spring Simulation, this step shows how to shift a widget from a dragged point back to the middle.

1st Step: Animation controller setup

2nd Step: Then, move the widget using gestures

3rd Step: Animating the Widget

4th Step: To simulate a springing motion, calculate the velocity

You may want to animate a widget to make it act like it’s connected to a spring or dropping with gravity, for example.

Here, Let’s take an example of Spring-simulation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
 
class SpringBasedAnimationExample extends StatefulWidget {
_SpringBasedAnimation createState() => _SpringBasedAnimation();
}
class _SpringBasedAnimation extends State<SpringBasedAnimationExample>
with SingleTickerProviderStateMixin {
AnimationController _animationController;
SpringSimulation _springSimulation;
 
@override
void initState() {
super.initState();
_springSimulation = SpringSimulation(
SpringDescription(
mass: 1,
stiffness: 100,
damping: 1,
),
0.0, // starting point
300.0, // ending point
10, // velocity
);
_animationController = AnimationController(
vsync: this,
upperBound: 500,
)..addListener(() {
print(_animationController.value);
setState(() {});
});
_animationController.animateWith(_springSimulation);
}
 
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Stack(children: [
Positioned(
left: 50,
top: _animationController.value,
height: 24.0,
width: 24.0,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.0),
color: Colors.blue,
),
),
),
]),
);
}
@override
void dispose() {
_animationController.dispose();
super.dispose();
}
}
Output:

Here, Because of the spring’s oscillation, the upper-bound value is greater than the ending point in simulation parameters.

Except as otherwise noted, see how the parameters of SpringSimulation influence the animation in these GIFs.

(Output)

WRAPPING UP!
So, we hope that you’re clear with flutter animation’s types, which are: Tween Animation and Physical-Based Animation. In the next part, we will discuss other types of flutter animation. Till then. Stay tuned!

Other than this, if you’re interested in gaining some interesting views on Flutter and Mobile App Development. Check out our Article on “Flutter vs. ReactNative vs. Xamarin” and “Mobile App Development Trends to follow in 2021”. If you liked this article, you’ll like others too.