Animations in Flutter

Muhammed Salih Guler
ProAndroidDev
Published in
7 min readJul 14, 2018

--

Animations are one of the essential things that enhances the user experience, makes your application more interactive and makes your users excited to use the application.

I was looking for my next topic to write for Flutter, then I saw this article about motion, usability, and animations and decided to create some of the animations described there with Flutter.

Credit: uxinmotion

In the scope of this article, we will cover:

  • Easing
  • Offset & Delay
  • Parenting
  • Transformation
  • Value change
  • Masking

If you are ready, let’s get started!

p.s. This article considers that you have a basic understanding about Flutter widgets and working environment.

Small intro to the animation components

Before we dive into the code, we need to cover some components. The first component is called Animation. Animation object is the object that gets the values that are given and translates those to meaningful animations. Since it’s not bound to any view on the screen, it is unaware of what is happening on the screen. But it has listeners to check out the state of the animation during each frame change.

T second component is called AnimationController. AnimationController class is the class to control the animation objects. We are using it to start the animation objects, give them durations and many more.

Next component is called Tween. Tween is a stateless object which only does the mapping from an input range to an output range. Normally the range of AnimationController is 0 to 1. For changing it, we are using Tween objects.

Another component we will be talking about is called Transition. This is a special widget that applies a transition before painting the child widget.

The last component we will be covering is called AnimatedBuilder. It creates a widget that can be animated with animation objects and controllers.

Easing Animation

We will start with the easing animation, the animation will bring a shape from the outer screen and leave the screen after waiting for a second. After animation finishes, the screen will be closed.

Let’s start by adding a stateful widget.

After that, we will create the Animation and the AnimationController object. We will initialise, these variables at theinitState method of State class so, they will be ready to use when the widget is created.

In the initState method, first, we created an AnimationController which states that animation will take 2 seconds. There is also a new variable called vsync. It is the ticker provider which we provide above with with TickerProviderStateMixin code snippet. Ticker is the class to notify the animation in each frame change.

The second object that we created in initState is our Animation object. First, we define the Tween object. That tween object states the animated object will come from the left side of the screen and stay in the middle but it’s not what we want (obviously).

In the build method, we are creating an AnimatedBuilder. It takes two variables as parameters. One is animation and we will pass our animation controller object there and the other is the builder, which we will be passing a widget. Since we want it to animate, we will be using Transform object as a base widget. It also takes two variables as parameters, one is transform and the other one is the child which will be transformed.

For thechild, we are passing a simple black square. For transform we are using Matrix4.translationValues(_animation.value * width, 0.0, 0.0) snippet. translationValues method gets x,y,z direction values and transforms the view according to given value (long sentence to handle, I know). In our case, we are getting the screen width and tween variable and transform our view in each frame change to the related position.

Lastly, we have a dispose method. When the view is disposed, we should release the controller resources to prevent leaks.

But when you call this widget and run the method you will be seeing that, it’s not working. Because you have not started your animation yet. For starting the animation, you are expected to call _controller.forward() in the place that you want to start it. In our case, it will be at build method. When you add it there, you will see that there is a square coming to the center of the screen but, do nothing more. For keep doing that, we need something called statusListeners.

Status listeners can give you information about status when it’s completed or reversed etc. What we will be doing here is, add a status listener and remove it when the animation completed, so it can start another animation. When the second animation stops, our screen will be closed and go back to the previous screen (or close the application in case you only have one widget).

If you update your initState method as it is above, you would be able to see a black box coming from left side of the screen, stays in the middle and leaves the screen from the right side.

Let’s show the GIF for the first one, we will have an overview video of all the animations that we implemented, at the end of the post.

We managed to the hard part. Rest of it, will be using the animations that we already know.

Offset & Delay Animation

For the offset and delay animation, we will be using most of the code that we created above. Difference will be, we will apply those animations to three different elements and one will be doing it with a delay.

For achieving this goal, we will be using a class called Interval. Interval is a class that can return a Curve object to CurvedAnimation. Interval is getting two important parameters. One is called begin other is called end . For Interval’s beginning of the project is 0.0 and end is 1.0 so you can pass two variables between these values to tell the animations to start in that exact point.

For the late animated view, we will create another animation object with an interval. Other two views will be using the previous animations that we created. We will also add callback part for the interval view, in the handler method that we created earlier.

We added a new animation with status handler. All we need to do is, call the animation object as we did in the previous example in an Transform object. Rest will be handled by the Flutter framework.

We are ready with this one too. Let’s proceed to the parenting animation.

Parenting Animation

In the parenting animation, we start of with two rectangles, one is small and the other one is big. We will be moving two of the rectangles to the center of the screen from the left border of the screen. Meanwhile we are moving it, we will be making the small rectangle as big as the big rectangle.

For starters, we will create an animation object to handle the growing animation. This animation will change the height and width of the view.

Another thing that we will be covering is a method comes from AnimationController. It is called reverse. This reverses the animation and it has it’s own status from status listener which is calleddismissed. We will use it to exit the screen when the reverse operation is finished.

For the moving animation, we will use the animation that we defined before. But we will change the animation value to -0.25 to start from the edge of the screen. At the end, our animation widget will look like this.

Transformation/Masking Animation

We will be handling transformation and masking animation together because in both we will be using the same animation. Only difference is in the masking animation, we will be putting a view to be masked by using Stack.

Since we are masking a square view, we can define a transforming animation which can handle both height and width. Also, for creating a circle in the beginning, we can give a border radius as begin value in a BorderRadiusTween and end value 0 to make it a rectangle.

In code our initState method will look like as follows.

When we create the views with animation information above, it will be doing the transition in to the height and width of the element to be masked.

We can proceed to the last one now.

Value Change Animation

Value change animation is one of the easy ones that can be implemented. There is a tween called IntTween and we can directly read the value by calling it. You can simply create a tween element by calling IntTween(begin: 0, end: 10) and assign begin and end values as the values that you want to have.

Conclusion

That was a lot of information and code to handle at once. But believe me, if you are into Flutter and if you are planning to develop applications using this platform this blog post will be useful for you.

Here is how the latest product looks like:

And you may see the code for the project above.

That was all for the blog post. Looking forward to next blog post!

--

--