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
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Adding AnimatedPositioned to the Radial Menu

Your Radial Menu is looking pretty good, but it needs an animation to match the rest of the application. To animate the menu buttons appearing, you're going to use the AnimatedPositioned widget.

AnimatedPositioned is the animated version of the Positioned widget. Use this widget to change the position and size of the widget. Here are a couple points to keep in mind while working with this widget:

  • It'll only work if its parent widget is Stack.
  • Although it's very useful, AnimatedPositioned is expensive, since it triggers a re-layout on every frame.

Navigate back to the radial_button file and replace the Positioned widget at the top of Build with an AnimatedPositioned widget. Then, add two new arguments to the new AnimatedPositioned:

duration: const Duration(milliseconds: 500),
curve: Curves.elasticIn,

The duration argument sets the duration for the animation.

The curve argument is more interesting. You can make your animation more realistic by adjusting its rate of change over time. This is where Curves comes in handy in Flutter.

That's it, you've finally implemented this complex animation! Save the project and build and run:

radial menu button using AnimatedPositioned

Implementing a Circular Progress Bar

As mentioned earlier, you may come across a situation where you want to develop a basic animation, but Flutter doesn't have the animated version of that property or widget. In these situations, try the custom implicit animation builder TweenAnimationBuilder. As you'll see, you don't need to call setState for this animation widget, unlike the other implicit animation widgets.

You'll use the following animation widget to create a circular progress bar in the app. Open statistics_widget.dart in widgets. Add the following method to StatisticsWidgetState:

Widget _tweenBuilder({
  double endValue,
  String statsName,
  Color color,
  double textSize,
}) {
  return TweenAnimationBuilder(
    // 1
    tween: Tween(begin: 0.0, end: endValue),
    // 2
    duration: const Duration(milliseconds: 1500),
    // 3
    curve: Curves.easeOutBack,
    // 4
    child: _labelWidget(statsName, textSize),
    // 5
    builder: (
      context,
      value,
      child,
    ) {
      return _circularProgressBar(
            color: color,
            value: value,
            labelWidget: child);
    },
  );
}

Here's an explanation of the numbered comments:

  1. The code passes a Tween object. Tween is a linear interpolation between the beginning value and the end value. You then pass these interpolated values to the property of the soon-to-be-animated widget.
  2. The code defines the duration of the widget's animation.
  3. Curves.easeOutBlack varies the rate of animation over the duration.
  4. In TweenAnimationBuilder, you can pass a widget in the child parameter that doesn't depend on the animation and is a child of the animated widget. This is a good practice since the child widget only builds once, unlike the animated widget, and results in better perfomance.

Before moving further, here are a few points that will be helpful while working with TweenAnimationBuilder:

  • You can trigger the animation any time in TweenAnimationBuilder by providing a new Tween.end value.
  • The new animation triggered by changing the value of Tween.end runs from the animation value at that moment to the new end value.

While still in StatisticsWidgetState, go to build and find the //TODO: tweenBuilder comment.

Delete this code:

_circularProgressBar(
  value: 0.4,
  color: Colors.blue,
  labelWidget: _labelWidget('Stationery Purchased', _textSize)),
_circularProgressBar(
  value: 0.3,
  color: Colors.green,
  labelWidget: _labelWidget('Planting Goal', _textSize)),

Replace the previous code with the following:

_tweenBuilder(
    statsName: 'Stationery Purchased',
    endValue: PlantStationeryConvertor.plantFraction,
    color: Colors.blue,
    textSize: _textSize),
_tweenBuilder(
    statsName: 'Planting Goal',
    endValue: PlantStationeryConvertor
            .plantingStatus.getPlantationGoal / 10,
    color: Colors.green,
    textSize: _textSize),

That's it. Save the project, and build and run to review all the things that you accomplished today! :]

circular progress bar using TweenAnimationiBuider

Where to Go From Here?

You can download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.

There are a few implicit animations that aren't covered in this tutorial. You can find them in Common implicitly animated widgets. Try adding more features into the app or replace used animation widgets with their alternatives, if possible.

Now is an ideal time to learn about the 12 Principles of Animations by the Disney animators Ollie Johnston and Frank Thomas. This will enable you to create more realistic and appealing animations in the future.

Also, check out the implicit animations video tutorial to get even more animation goodness in your life!

We hope you liked this tutorial. If you want more articles like this or have any questions, let us know by using the comments section below!