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.

Leave a rating/review
Download materials
Save for later
Share

Don’t you love apps that give you a rich and fluent experience? They’re such a pleasure to use. Every single transition, from opening the app to switching between pages to expanding an element, feels so good. How cool would it be to make that kind of app yourself? Well, you can! Today, you’ll create a Flutter app with some great effects using implicit animations.

By the end of this tutorial, you’ll learn about the following topics:

  • Animations in Flutter, with a focus on implicit animations.
  • Making a responsive TextField.
  • Adding a cross-fade between widgets.
  • Animating a page transition.
  • Creating an expanding radial menu.
  • Implementing a circular progress bar.
Note: This tutorial assumes that you have a basic knowledge of widgets. For help with the basics, please check the tutorials on Getting Started with Flutter and Responsive Design for Flutter.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial. Unzip the file after the download is complete. This tutorial uses Visual Studio Code, but you can also use Android Studio. If you choose Android Studio, some instructions may vary, so you’ll need to adapt those.

Open Visual Studio Code and click Open folder… on the welcome page, or select File ▸ Open… from the menu, then browse and choose the Starter folder from your unzipped download.

After opening the starter project, you will see a lot of errors in the code. Get rid of the errors by (1) double-clicking pubspec.yaml on the left-side panel and then (2) clicking the Get Packages button at the top of your screen. Alternatively, you could (3) open the Terminal in Visual Studio Code and (4) type flutter pub get, then click Enter.

get dependencies

Start the emulator of your choice, then build and run the app. At this point, you should see the following:

non-animated app

The starter project is an app with no animations. You’ll change this by giving your app some cool animations. Before taking that journey, here’s a short introduction to the app you’ll make:

The company Green Stationery promises to plant a tree to help the environment after a customer buys a certain number of products. This app sets the planting goals for you based on the stationery items you buy.

Understanding the Starter Project

The important files for this tutorial are:

  • lib/screens/greetings_screen.dart: This is the very first screen that you see when opening the app. It includes the text field to take the user name and a greeting card.
  • lib/screens/overview_screen.dart: This screen provides the details related to your consumption of stationery items and assigned planting goals.
  • lib/widgets/stationery_list.dart: This is a list widget that shows the consumption value of stationery types.
  • lib/widgets/statistics_widget.dart: This contains a stack widget with several other widgets as its children. It contains all the widgets shown on the overview screen except the stationery list widget.

Before doing any coding, though, it’s important to understand how animations work in Flutter.

Animations in Flutter

It’s important to understand a few things about motion and your smartphone screen’s refresh rate before starting. According to the Wikipedia article Frame rate, “The human visual system can process 10 to 12 images per second and perceive them individually, while higher rates are perceived as motion.”

Therefore, if you see more than 12 successive images of a moving ball every second, you’ll perceive them as motion rather than individual images. The more images per second, the smoother the motion. Today’s smartphones have a refresh rate of 60 frames per second or higher.

Animations in Flutter let you rebuild parts of your widget on every refresh of your device screen. To animate the widget in Flutter, you provide details such as when the animation should happen and how the properties of your widget should vary. The following demo will give you a better understanding.

Seeing an Animation in Slow Motion

Open the file lib/screens/demo/demo_screen.dart and replace the code with the following:

//1
import 'dart:async';
import 'package:flutter/material.dart';

class DemoScreen extends StatefulWidget {
  const DemoScreen({Key key}) : super(key: key);
  @override
  State createState() {
    return DemoScreenState();
  }
}

class DemoScreenState extends State {
  int steps = 0;

  void update() {
    //2
    Timer.periodic(
      const Duration(seconds: 1),
       //3
      (timer) => setState(
        () {
          steps < 20 ? steps = steps + 1 : timer.cancel();
        },
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Animations Mystery!'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Stack(
          children: [
            Center(
              child: Container(
                //4
                width: 50.0 + steps * 5,
                height: 50.0 + steps * 5,
                color: Colors.blue[900],
              ),
            ),
            Align(
              alignment: Alignment.bottomRight,
              child: FloatingActionButton(
                  child: const Icon(Icons.add), onPressed: update),
            )
          ],
        ),
      ),
    );
  }
}

Here's what this code does:

  1. First you import the dart:async library, which supports asynchronous programming. It allows you to use Timer.
  2. Next, you're calling Timer.periodic(), which allows you to repeatedly trigger a callback function until you call Timer.cancel().
  3. This is the callback function that you're supplying to Timer.periodic(). It will be called repeatedly.
  4. Finally, these are the properties of the widget that you'll animate.

To see this code in action, open lib/main.dart and replace home: const GreetingsScreen() with:

home: const DemoScreen(),

Now, import the demo_screen.dart file as follows:

import 'package:green_stationery/screens/demo/demo_screen.dart';

Save the project, then build and run:

animation education using demo animation

When you click the floating button, the container size increases linearly every second. Animations in Flutter work similarly, but much faster and in a way more visually pleasing to the user.

The demo was temporary, so while you're still in lib/main.dart, replace home: const DemoScreen() with the following, as it was before:

home: const GreetingsScreen(),

Remove the unused import:

import 'package:green_stationery/screens/demo/demo_screen.dart';

Build and run the app again to make sure it works as before:

non-animated app

Still works. It's time to learn more about the types of animations that Flutter has.

Explicit and Implicit Animations

Broadly speaking, there are two types of animations in Flutter:

  • Drawing-based animation: These animations looks like someone drew them. They're hard to implement purely via code.
  • Code-based animation: These animations are widget-focused. They can be easily implemented purely via code. You'll look into a subtype in this tutorial.

Code-based animations have two types, as shown below:

code-based animation in Flutter

  • Implicit animations: These are animations that are already programmed. This means that you don’t need to write the animation code yourself; you only need to change some properties or values.
  • Explicit animations: These are animations that involve building customized animations using the AnimatedBuilder widget. This means that you can customize some properties or animation elements.
Note: This tutorial will focus on implicit animations. Read more about explicit animations in Flutter's official documentation.

Implicit animations are, once again, divided into two types:

  • AnimatedFoo: AnimatedFoo widgets are built-in implicit animation widgets. The Foo in AnimatedFoo represents the property you want to animate. For example, AnimatedSize animates the size. This type of animation is the easiest to implement.
  • Custom implicit animation: If you can't find a built-in implicit animation that meets your needs, you can use TweenAnimationBuilder to create a custom implicit animation.