flutter animatedcontainer

What is the Flutter AnimatedContainer and how to use it

What is the Flutter AnimatedContainer

Flutter AnimatedContainer is a widget that helps you create animations for different parts of your app. It works by changing the properties of a container, such as its size, position, and colour, over a period of time. This makes it look like the container is moving, changing size, or changing colour. The properties change smoothly, giving the animation a nice and smooth look.

It’s a simple way to create animations, you don’t have to write a lot of code to make it work. It’s useful for creating animations for different parts of your app, like making a button grow when you press it or making a container move to a new position on the screen. It can also be used in combination with other animation widgets to create more complex animations.

It’s easy to use and lightweight, making it a great option for creating animations in your app without adding too much complexity. It’s also a great option for beginners who are just learning to create animations in Flutter.

How to use AnimatedContainer in Flutter

Here’s an example of how to use the AnimatedContainer to animate the width of a container:

double _width = 100;

Center(
  child: GestureDetector(
    onTap: () {
      setState(() {
        _width = _width == 100 ? 200 : 100;
      });
    },
    child: AnimatedContainer(
      width: _width,
      height: 100,
      duration: Duration(seconds: 1),
      curve: Curves.easeInOut,
      decoration: BoxDecoration(
        color: Colors.blue,
      ),
    ),
  ),
)

In this example, the AnimatedContainer’s width is set to a variable _width. When the container is tapped, the state of the widget is updated, which triggers a rebuild of the widget tree. The new width value is passed to the AnimatedContainer, which smoothly animates the width of the container over a duration of 1 second using the ease-in-out curve.

You can also animate other properties of the container like color, padding, and margin using the AnimatedContainer.

It’s important to note that, when you want to animate a property, you should set it to a variable and use this variable as the value of the property in the AnimatedContainer. In this way, when the variable changes, the animation will be triggered.

You can also use animationController to control the animation, you can pause, resume, and reverse the animation.

You can also use different animation curves to control the speed of the animation. Flutter provides a number of built-in curves like Curves.easeInOut and Curves.bounceIn.

Where I use AnimatedContainer in Flutter

The AnimatedContainer can be used in many different parts of a Flutter app to create animations. Here are a few examples:

  1. Navigation: You can use the AnimatedContainer to animate the transition between different screens or pages in your app. For example, you can use it to animate the position or size of a container when navigating to a new screen.
  2. Loading Screens: You can use the AnimatedContainer to create a visually appealing loading screen while the app loads data or resources in the background.
  3. User Interface Elements: You can use the AnimatedContainer to create animations for different user interface elements, such as buttons, forms, and lists. For example, you can use it to animate the size of a button when it’s pressed or to animate the position of a form field when it’s focused.
  4. Custom Loading Indicator: You can use the AnimatedContainer to create a custom loading indicator for your app, such as a spinning wheel or a progress bar.
  5. Responsive design: You can use the AnimatedContainer to create responsive designs that adapt to different screen sizes. For example, you can use it to animate the size of a container when the screen size changes.
  6. Complex animations: You can use the AnimatedContainer in combination with other animation widgets, such as AnimatedOpacity and AnimatedPositioned, to create more complex animations.
  7. Game development: You can use the AnimatedContainer to animate different elements in a game, such as the character, the background, or the score.
  8. Dynamic UI: You can use the AnimatedContainer to create a dynamic UI that changes based on user input or data changes. For example, you can use it to animate the size or colour of a container when a user selects an option from a drop-down menu.

These are just a few examples of how you can use the AnimatedContainer in a Flutter app, the possibilities are almost endless.

Flutter AnimatedContainer properties

The AnimatedContainer widget in Flutter is a widget that allows you to animate the properties of a container, such as its width, height, color, and more. It takes a child widget, which is the widget that will be inside the container, as well as a set of properties that can be animated.

The following properties can be animated:

  • duration: The length of the animation, in milliseconds.
  • curve: The animation curve to use. This can be one of the predefined curves, such as Curves.easeIn, or a custom curve created using the Curve class.
  • width: The width of the container.
  • height: The height of the container.
  • color: The color of the container.
  • padding: The padding around the child widget.
  • margin: The margin around the container.
  • decoration: A decoration to paint behind the child widget.

The following methods are available for use in the AnimatedContainer widget:

  • animate: Triggers the animation of the properties.
  • addListener: Register a callback to be invoked when the animation changes.
  • addStatusListener: Register a callback to be invoked when the animation changes its status.
  • setState: Mark the widget as needing to rebuild.

The AnimatedContainer widget also has a AnimationController property which is used to control the animation. It can be used to pause, resume, reverse, and stop the animation.

Here’s an example of how you might use the AnimatedContainer:

AnimatedContainer(
    duration: Duration(seconds: 1),
    curve: Curves.fastOutSlowIn,
    width: _width,
    height: _height,
    color: _color,
    child: SomeWidget(),
);

In this example, the width, height, and colour of the container will be animated over a period of 1 second, using the fastOutSlowIn curve. The child widget inside the container is SomeWidget().

Note that, in order to use the AnimatedContainer, you will need to create a StatefulWidget and use the setState method to trigger the animation.

Flutter AnimatedContainer example

flutter animatedcontainer

Here’s an example of how you might use the AnimatedContainer with all the properties and methods I mentioned earlier (an explanation of the code is below):

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {

  late AnimationController _animationController;
  late Animation<double> _widthAnimation;
  late Animation<double> _heightAnimation;
  late Animation<Color?> _colorAnimation;
  late Animation<EdgeInsets> _paddingAnimation;
  late Animation<BorderRadius?> _borderRadiusAnimation;

  double _width = 100;
  double _height = 100;
  Color _color = Colors.blue;
  EdgeInsets _padding = EdgeInsets.all(8);
  BorderRadius _borderRadius = BorderRadius.circular(8);

  @override
  void initState() {
    _animationController = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    );

    _widthAnimation = Tween<double>(begin: 100, end: 200).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Curves.easeInOut,
      ),
    );

    _heightAnimation = Tween<double>(begin: 100, end: 200).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Curves.easeInOut,
      ),
    );

    _colorAnimation = ColorTween(begin: Colors.blue, end: Colors.red).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Curves.easeInOut,
      ),
    );

    _paddingAnimation = EdgeInsetsTween(
      begin: EdgeInsets.all(8),
      end: EdgeInsets.all(50),
    ).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Curves.easeInOut,
      ),
    );

    _borderRadiusAnimation = BorderRadiusTween(
      begin: BorderRadius.circular(8),
      end: BorderRadius.circular(100),
    ).animate(
      CurvedAnimation(
        parent: _animationController,
        curve: Curves.easeInOut,
      ),
    );

    _animationController.addListener(() {
      setState(() {
        _width = _widthAnimation.value;
        _height = _heightAnimation.value;
        _color = _colorAnimation.value!;
        _padding = _paddingAnimation.value;
        _borderRadius = _borderRadiusAnimation.value!;
      });
    });

    _animationController.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        _animationController.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _animationController.forward();
      }
    });

    _animationController.forward();

    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text('flutterassets.com'),
      ),
      body:
      Center(
        child: AnimatedContainer(
          duration: Duration(milliseconds: 100),
          curve: Curves.fastOutSlowIn,
          width: _width,
          height: _height,
          decoration: BoxDecoration(
            color: _color,
            borderRadius: _borderRadius,
          ),
          padding: _padding,
          child: Center(
            child: Text("Animated Container"),
          ),
        )
      )
    );
  }
}

In this example, the width, height, colour, padding and borderRadius of the container are animated over a period of 1 second, using the fastOutSlowIn curve. The child widget inside the container is a Text("Animated Container") which is centered.

In the initState() function, we have created a AnimationController, this controller is the one that controls the animation. We have created separate animation for width, height, colour, padding and borderRadius and passed the controller to the animation and set the start and end values for each animation.

We have also added a listener to the _animationController which updates the values of the properties as the animation progresses and also added a status listener which reverses the animation when it completes and starts it again when it is dismissed.

In the build() method, we use the AnimatedContainer widget and pass in the animated properties.

Lastly, in the dispose() method, we dispose the _animationController to prevent any memory leaks.

Flutter AnimatedContainer example breakdown

Here is a breakdown of the code I provided earlier:

Variables

In this code, we have the following variables:

  • _animationController: An instance of the AnimationController class, which controls the animation.
  • _widthAnimation: An instance of the Animation class, which animates the width of the container.
  • _heightAnimation: An instance of the Animation class, which animates the height of the container.
  • _colorAnimation: An instance of the Animation class, which animates the colour of the container.
  • _paddingAnimation: An instance of the Animation class, which animates the padding of the container.
  • _borderRadiusAnimation: An instance of the Animation class, which animates the border radius of the container.
  • _width: A double value, which stores the current width of the container.
  • _height: A double value, which stores the current height of the container.
  • _color: A Color value, which stores the current colour of the container.
  • _padding: An instance of EdgeInsets, which stores the current padding of the container.
  • _borderRadius: An instance of BorderRadius, which stores the current border radius of the container.
The initState() method

In the initState() method, we do the following:

  • Create an instance of AnimationController and set its duration to 2 seconds and the vsync property to this.
_animationController = AnimationController(
  duration: Duration(seconds: 2),
  vsync: this,
);
  • Create different animations for each property (width, height, colour, padding, borderRadius) and set their values, curve and pass the controller to it.
_widthAnimation = Tween<double>(begin: 100, end: 200).animate(
  CurvedAnimation(
    parent: _animationController,
    curve: Curves.easeInOut,
  ),
);

_heightAnimation = Tween<double>(begin: 100, end: 200).animate(
  CurvedAnimation(
    parent: _animationController,
    curve: Curves.easeInOut,
  ),
);

_colorAnimation = ColorTween(begin: Colors.blue, end: Colors.red).animate(
  CurvedAnimation(
    parent: _animationController,
    curve: Curves.easeInOut,
  ),
);

_paddingAnimation = EdgeInsetsTween(
  begin: EdgeInsets.all(8),
  end: EdgeInsets.all(50),
).animate(
  CurvedAnimation(
    parent: _animationController,
    curve: Curves.easeInOut,
  ),
);

_borderRadiusAnimation = BorderRadiusTween(
  begin: BorderRadius.circular(8),
  end: BorderRadius.circular(100),
).animate(
  CurvedAnimation(
    parent: _animationController,
    curve: Curves.easeInOut,
  ),
);
  • Add a listener to the animation controller, the listener updates the value of the properties as the animation progresses
_animationController.addListener(() {
  setState(() {
    _width = _widthAnimation.value;
    _height = _heightAnimation.value;
    _color = _colorAnimation.value!;
    _padding = _paddingAnimation.value;
    _borderRadius = _borderRadiusAnimation.value!;
  });
});
  • Add a status listener to the animation controller, the listener checks for the status of the animation and reverses it when it completes, and starts it again when it is dismissed
_animationController.addStatusListener((status) {
  if (status == AnimationStatus.completed) {
    _animationController.reverse();
  } else if (status == AnimationStatus.dismissed) {
    _animationController.forward();
  }
});
  • Start the animation
_animationController.forward();
The build() method

In the build() method, we use the AnimatedContainer widget and pass in the animated properties as follows:

return AnimatedContainer(
  duration: Duration(milliseconds: 100),
  curve: Curves.fastOutSlowIn,
  width: _width,
  height: _height,
  decoration: BoxDecoration(
    color: _color,
    borderRadius: _borderRadius,
  ),
  padding: _padding,
  child: Center(
    child: Text("Animated Container"),
  ),
);
The dispose() method

In the dispose() method, we dispose the _animationController to prevent any memory leaks.

@override
void dispose() {
  _animationController.dispose();
  super.dispose();
}

It is important to dispose the animation controller when it is no longer needed to avoid memory leaks and other related issues.