New! Unlimited audio, video & web asset downloads! Unlimited audio, video & web assets! From $16.50/m
  1. Code
  2. Android SDK

Google Flutter From Scratch: Animating Widgets

This post is part of a series called Google Flutter From Scratch.
Google Flutter From Scratch: Grids, Lists, and Data Sources
Google Flutter From Scratch: Using Firebase Services

Animations, when used correctly, can make a huge difference in how users perceive your app. An app with lots of quick, subtle animations tends to look a lot more polished and professional than one without. On Google Play, an overcrowded marketplace, that can mean the difference between success and failure.

Flutter is perhaps the only hybrid app development framework available today that allows you to create complex animations that can run constantly at 60 frames per second. In this tutorial, I'll help you understand the basics of animating Flutter widgets. I'll also introduce you to a few new widgets that can simplify your animation code.

1. Preparing a Widget for Animation

The Flutter framework expects you to follow a functional, reactive approach to programming. Therefore, to be able to animate a widget, you must be able to update its state repeatedly, at well-timed intervals.

To create a widget that's easy to animate, start by creating a class that extends the StatefulWidget class and overriding its createState() method. Inside the method, make sure you return a State instance.

In order to be animatable, the state object you associate with your stateful widget must not only extend the State class, it must also use a mixin called SingleTickerProviderStateMixin. As its name suggests, the mixin offers a Ticker object, which repeatedly generates callbacks, conventionally known as ticks. Because the ticks are generated repeatedly at uniform intervals of time, you can use them to decide when the individual frames of your animation are rendered.

2. Creating a Tween Animation

A tween animation is one of the simplest animations you can create with Flutter. While creating it, all you need to do is provide two different values: a starting value and an ending value. The framework will then automatically generate a set of intermediate values—or in-between values—that start from the starting value and smoothly grow to match the ending value. By gradually applying those intermediate values to a property of your widget, you animate that property.

Let's now create a simple tween animation that moves a widget from the top left corner of the screen to the top right corner of the screen. In other words, let's animate the left property of a widget.

To create and control the animation, you're going to need an Animation object and an AnimationController object. Add them as member variables of your state:

You must initialize both objects by overriding the initState() method of your class. Inside the method, call the constructor of the AnimationController class to initialize the controller. It expects a TickerProvider object as one of its inputs. Because the state already uses the SingleTickerProviderStateMixin mixin, you can pass this to it. Additionally, you can use the duration property to specify the duration of the animation.

The following code creates an animation controller whose duration is four seconds:

At this point, you can create a Tween object specifying the beginning and ending values of your animation.

To associate the Tween object with the AnimationController object, you must call its animate() method. The return value of the method is an Animation object, which you can store in the second member variable of your class.

The Animation object generates an animation event for every tick of the ticker, which you must handle for your animation to work. To do so, you can use its addListener() method. Additionally, inside the event handler, you must call the setState() method to update the state of your widget and redraw it. The following code shows you how:

Note that you don't have to write any code inside the setState() method unless you have other state variables to update.

Lastly, to start the animation, you must call the forward() method of the animation controller.

The animation is ready. However, you still haven't applied it to any widget that is being drawn on the screen. For now, I suggest you apply it to a Positioned widget containing a Material Icon widget. To do so, while creating the widget, simply set the value of its left property to the value property of the Animation object.

Accordingly, add the following code, which overrides the build() method, to the state:

Note that there's a Stack widget in the above widget tree because a Positioned widget must always be embedded inside one.

You can run your app now to see the animation.


3. Handling Animation Status Events

If you want to be notified when your animation has ended, you can attach an AnimationStatusListener object to your Animation object. Inside the listener, if the current animation status is completed or dismissed, you can be sure that the animation has ended.

Tween animations in Flutter are reversible. That's the reason why there are two different status constants signifying the end of an animation. If the current status is completed, it means that the animation has ended at the end value of the tween. If it is dismissed, it means that the animation has ended at the start value. Using the two statuses and the forward() and reverse() methods, you can easily create to and fro between animations.

The following code, which you can add to the initState() method, shows you how to reverse and repeat the animation you created in the previous step:

If you run the app again, you should see the animation repeat endlessly.


4. Using Animated Widgets

The Flutter framework offers a few readily animatable widgets you can use to make your animation code slightly less verbose and more reusable. All of them are subclasses of the AnimatedWidget class and expect Animation or AnimationController objects in their constructors.

One of the most commonly used animated widgets is the RotationTransition widget. It allows you to quickly apply a rotation animation to its children. To use it, first create a new animation controller. The following code creates one whose duration is set to six seconds:

To start the animation this time, instead of the forward() method, use the repeat() method. This ensures that the animation repeats endlessly.

To keep things simple, you can use a Text widget as the child of the RotationTransition widget. So create a widget tree accordingly. While creating the RotationTransition widget, though, make sure you set the value of its turns property to the AnimationController object you just created. Optionally, you can place both the widgets inside a Center widget. Here's how:

In the above code, I've used a Unicode emoji codepoint as the contents of the Text widget. This is allowed because Flutter supports emoji right out of the box.

On running the app again, you should see something like this on your screen:


Very similar to the RotationTransition widget is the ScaleTransition widget. As you may have guessed, it allows you to animate the scale of its children. While creating it, all you need to do is pass the AnimationController object to its scale property. The following code shows you how you:

You'll now be able to see the Text widget's scale change during the animation.


If you're wondering why we didn't create any Tween objects for the above animations, it's because, by default, the AnimationController class uses 0.0 and 1.0 as the begin and end values.

5. Using Curves

All the animations we created in earlier steps followed a linear curve. As a result, they don't look very realistic. By altering the way the Tween object generates intermediate values, you can change that.

Flutter has a class called CurvedAnimation, which allows you to apply non-linear curves to your tweens. When you use it with the Curves class, which offers a variety of curves, such as easeIn and easeOut, you can create animations that feel more natural.

To create a CurvedAnimation object, you'll need an AnimationController object as a parent. You are free to use one of the controllers you created in earlier steps or create a new one. The following code creates a new controller whose duration is set to five seconds, and a CurvedAnimation object whose curve property is set to a bounceOut curve:

You can now create a Tween object and apply the CurvedAnimation object to it by calling its animate() method. Once the animation is ready, don't forget to add a listener to the animation, update the state, and then call the forward() method to start it.

To see the animation, let's apply it to a Positioned widget's top property. You're free to add any child widget inside it. In the following code, I add a Text widget displaying another emoji.

After a hot restart, your app should now show the following animation:



You now know the basics of creating tween animations using the Flutter framework. In this tutorial, you also learned how to make them appear more natural using curves. Do understand that in the slow mode, which is the default mode during development, the animations may seem a little laggy and unsteady. It's only in the release mode that you can see their true performance.

To learn more, do refer to the official documentation.

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.