Flutter8 min read

Flutter and animations – how to create smooth and responsive user interactions?

Female placeholder team

Róża Kazenas

Flutter Developer

Flutter and animations - how to create smooth and responsive user interactions?

Flutter is a popular framework for creating applications for both Android and iOS using one codebase. One of the advantages of Flutter is its fast rendering on a device and responsive user interface that allows user to navigate through the application without any lags or delays.

In this article we’ll explore even more smooth user interface by incorporating Flutter animations in your application which can enhance the experience of your users and bring them new value. You can open your Android Studio or VS Code to really make some use of the provided examples. Flutter animation objects is something definitely worth mentioning.

Implicit animations

We’ll start with one of the easiest way to animate your app by adding implicit animations. The main advantage to use implicit animations is that they are easy to implement and require less code making them perfect for simple use cases.

Implicit animations are a type of animations that occurs automatically when state of a widget or its properties changes. Everything you need to create this simple animations are included in Flutter framework and require no additional libraries. All the animations are happening here by transitioning between old and new value. For example we can use AnimatedContainer class to change height of the container, set duration and it can smoothly change its properties in specified time. This code snippet below presents AnimatedContainer that changes its properties when user clicks on FloatingActionButton by adding 10 to Container height.

class _MyHomePageState extends State<MyHomePage> {
  double _containerHeight = 100;

  void animateContainer() {
    setState(() {
      _containerHeight += 10;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            AnimatedContainer(
              height: _containerHeight,
              width: 100,
              color: const Color(0xffeb3492),
              duration: const Duration(
                seconds: 1,
              ),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: animateContainer,
        tooltip: 'Animate',
        child: const Icon(Icons.play_arrow),
      ), 
    );
  }
}

If you want to add some custom behaviour to AnimatedContainer you can specify the curve. It determines how animation is changing over time. Check out Flutter documentation to choose and experiment with different types of curves.

This simple example is a good reflection of other implicit animation widgets. Here is the full list from documentation.

Explicit animations

Now we are ready to move on to more complex animations, explicit animations. They are triggered manually using an AnimationController or Animation object.

Step 1: Create an Animation Controller

First step to creating explicit animations would be to add AnimationController which allows you to perform tasks such as: play a certain animation forward, reverse or stop or set its value as well as defining animation duration, curve and listener for the animation.

AnimationController _animationController;

@override
void initState() {
  super.initState();
  _animationController = AnimationController(
    vsync: this,
    duration: Duration(seconds: 1),
  );
}

Step 2: Create an Animation Object

The next step is to create an animation object. This object defines the range of values that the animation will use over time. You can create an animation object using the following code:

Animation<double> _animation;

@override
void initState() {
  super.initState();
  _animationController = AnimationController(
    vsync: this,
    duration: Duration(seconds: 1),
  );
  _animation = Tween<double>(
    begin: 0,
    end: 1,
  ).animate(_animationController);
}

In this example, we create an animation object that ranges from 0 to 1 over the course of one second. We use the Tween class to define the range of values that the animation will use. Set a current animation value and check out how it works to get the picture. You’ll see that two values that differ result in different effect (as mentioned earlier).

Step 3: Create the Animated Widget

Yo need to create the animated widget that will be displayed on the screen. You can use the AnimatedBuilder widget to create an animated widget that will update whenever the animation updates. Here’s an example of how to use AnimatedBuilder:

@override
Widget build(BuildContext context) {
  return AnimatedBuilder(
    animation: _animationController,
    builder: (context, child) {
      return Transform.scale(
        scale: _animation.value,
        child: Container(
          height: 100,
          width: 100,
          color: Colors.blue,
        ),
      );
    },
  );
}

In this example, we create a Transform.scale widget that scales the size of the container based on the value of the animation. The AnimatedBuilder widget listens to updates from the animation controller and rebuilds the widget tree whenever the animation updates. Hot reload is really a cool thing.

Step 4: Trigger the Animation

Finally, we need to trigger the animation to start. You can do this by calling the forward() method on the animation controller. Here’s an example:

void _startAnimation() {
  _animationController.forward();
}

In conclusion, explicit animations in Flutter provide a powerful way to create engaging and interactive animations in your app. By following the steps outlined above, you can create custom animations that bring your app to life and enhance the user experience. After a while you’ll be able to predict the final animation.

Hero animations

Another good use case for flutter animation in your mobile application is to create hero animations. You can use them to smoothly transition between screens by sharing a similar widget and adding some shared behaviour like enlarging it while changing screens. In effect your app will be more engaging and fluid.

To implement this type of animations you need to create an app with two different screens and then just wrap your two widgets in the widget tree in Hero widget to obtain an easy transition. Make sure to use the same tag and check out the source code for this simple example:

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {

  void _goToTheNextPage() {
    Navigator.of(context).push(
      MaterialPageRoute(builder: (context) =>  MySecondPage())
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Hero(
              tag: 'move',
              child: Container(
                height: 50,
                width: 50,
                color: const Color(0xffeb3492),
              ),
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _goToTheNextPage,
        tooltip: 'Navigate',
        child: const Icon(Icons.navigate_next),
      ),
    );
  }
}

class MySecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Hero(
              tag: 'move',
              child: Container(
                height: 500,
                width: 500,
                color: const Color(0xffeb3492),
              ),
            )
          ],
        ),
      ),
    );
  }
}

Staggered animations

Now we have many animations to choose from to build a beautiful flutter application but let’s add yet another one: staggered animations. They refer to a technique of triggering animations in a sequence, with a delay between each animation. This created a cascading effect, where each iteration begins after a certain amount of time giving the appearance of a flowing motion. Staggered animations can be used in various ways to create visually interesting effects such as cascading menus, expanding and collapsing lists and loading indicators. How to implement them depends on a specific use case. Here are some common approaches:

  1. Using AnimatedList widget: you can specify a delay for each item in the list, so each item animates in sequence. To use the AnimatedList, you need to provide an AnimationController that controls the durations and timing of the animations.
  2. Using the staggered animation builder. It’s a widget that allows you to create a sequence of animations with a specific delay between each animation. This widget can be used to create a variety od effects, such as a staggered grid of images, or a list with animations that trigger when the user scrolls.
  3. Using custom animations – if built-in widgets don’t provide desired effects, you can create custom animations that run on a specified timeline with a delay between each animation. Practice for a while to understand how to achieve certain duration.

Animations built using external tools

Another way to add a new value to your mobile apps is to use one of a several external tools that can be used to create animations and export them for use in Flutter applications. Here are some popular tools:

  • Adobe After Effects: a popular animation and visual effect software that allows you to create complex animations and export them in various formats by a plugin called Lottie.
  • Flare: a vector design and animation that has a Flutter runtime library to use animations directly in your Flutter code.
  • Figma: with a plugin called Flutter Interact you can export designs and animations ad Flutter code. This code can be used to create animations directly within your Flutter application.
  • Sketch: a vector graphics editor that is popular among designers. It has a plugin Sketch2Flutter that allows you to export designs and animations just like in Figma.

Summary

In conclusion, Flutter is a powerful and versatile framework for creating cross-platform mobile applications. By incorporating animations into your app, you can enhance the user experience and bring added value to your users. With the use of implicit animations, explicit animations, hero animations, and staggered animations, you can create smooth and responsive user interfaces that keep your users engaged. Flutter’s built-in animations and the ease of creating custom animations make it an excellent choice for any mobile app development project. By exploring the various animation techniques and experimenting with them, you can bring your mobile applications to life and create an engaging experience for your users.


Female placeholder team

Róża Kazenas

Flutter Developer

Post article


4.8/5 - (5 votes)

Got a project? Let’s talk!

Contact us