An introduction to Flutter Animation Basics

Animation in Flutter is of two types. The Implicit and the Explicit. The Implicit Animation refers to built-in Animated Widgets. Moreover, they are easier than the Explicit Animation.

Therefore, today, let us start with one such Implicit Animation. The AnimatedContainer.

By the way, the Implicit Animations are named like the “Animated-Widget”. In such cases, the term Widget stands for the non-animated Widget. It is also true for the AnimatedContainer.

By default the Container Widget in Flutter refers to the Layout Widgets.

However, the AnimatedContainer is an Animated version of the Container Widget. When the Container is Animated, it gradually changes its values over a period of time.

Let us take a look at the screenshots before we start.

Two Animated Container Widgets before the Animation starts
Two Animated Container Widgets before the Animation starts

The code is quite simple. Even Flutter Beginners can understand.

Firstly, we have placed two AnimatedContainer Widgets inside a Column Widget.

As a matter of fact, the AnimatedContainer always needs a new value so that it can change its old value. As a result, if we want to change the width, height and color of the AnimatedContainer, we need to place it inside a Stateful Widget.

In addition, inside the “setState()” method, we need to change the Boolean value from the “FALSE” to “TRUE”.

Let us take a look at the code snippet. As I said earlier, it is very simple.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Animated Container Example';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const MyStatefulWidget(),
      ),
    );
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  bool selected = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        setState(() {
          selected = !selected;
        });
      },
      child: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            MyAnimatedContainer(
              selected: selected,
              newDuration: const Duration(seconds: 2),
              src:
                  'https://cdn.pixabay.com/photo/2021/08/25/20/42/field-6574455_960_720.jpg',
            ),
            const SizedBox(
              height: 10.0,
            ),
            MyAnimatedContainer(
              selected: selected,
              newDuration: const Duration(seconds: 10),
              src:
                  'https://cdn.pixabay.com/photo/2021/11/13/23/06/tree-6792528_960_720.jpg',
            ),
          ],
        ),
      ),
    );
  }
}

class MyAnimatedContainer extends StatelessWidget {
  const MyAnimatedContainer({
    Key? key,
    required this.selected,
    required this.newDuration,
    required this.src,
  }) : super(key: key);

  final bool selected;
  final Duration newDuration;
  final String src;

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      width: selected ? 200.0 : 100.0,
      height: selected ? 50.0 : 100.0,
      color: selected ? Colors.indigoAccent : Colors.yellowAccent,
      alignment: selected ? Alignment.center : AlignmentDirectional.topCenter,
      duration: newDuration,
      curve: Curves.fastOutSlowIn,
      child: Image.network(src),
    );
  }
}

Through our custom Animated Container, we have passed three parameters.

By changing this three parameters in two separate Animated Containers, we have controlled each Animation.

children: [
            MyAnimatedContainer(
              selected: selected,
              newDuration: const Duration(seconds: 2),
              src:
                  'https://cdn.pixabay.com/photo/2021/08/25/20/42/field-6574455_960_720.jpg',
            ),
            const SizedBox(
              height: 10.0,
            ),
            MyAnimatedContainer(
              selected: selected,
              newDuration: const Duration(seconds: 10),
              src:
                  'https://cdn.pixabay.com/photo/2021/11/13/23/06/tree-6792528_960_720.jpg',
            ),
          ],

As a rule, the AnimatedContainer has a required parameter – the “duration”.

It controls the time. For the first custom Animated Container we have made it 2 seconds. And for the second custom Animated Container it is 10 seconds.

We could have also controlled the “curve” property. Because the “duration” and the “curve” parameters must not be “NULL”.

When properties are “NULL”, they are not animated.

Now, if we click any one of the images, two images start animating.

Two Animated Container Widgets after the Animation starts
Two Animated Container Widgets after the Animation starts

As a result, the Container with its internal AnimationController starts animating.

For more complex animations, we might have used a subclass of AnimatedWidget. We can use the DecoratedBoxTransition or we can use the AnimationController.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

GitHub repository

Technical blog

Twitter

Comments

2 responses to “An introduction to Flutter Animation Basics”

  1. […] we manage the Flutter Animation with Provider? Yes, we can do. We can always tackle the “State Management” with […]

  2. […] In earlier days of Animation, the main artist drew the key-frames. After that, another artist created the frame-by-frame Animation. […]

Leave a Reply