What
    Guide to Flutter Implicit Animations
    Why
    Learn how to implement basic animations in Flutter using implicit animated widgets like AnimatedContainer, AnimatedPositioned, and AnimatedOpacity.
    How
    Flutter can animate literally anything using the Skia graphics library. Implicit animations use widgets like AnimatedContainer, AnimatedPositioned, and AnimatedOpacity.
    Tech TrendsFlutterMobile Development

    Guide to Flutter Implicit Animations

    Looking for an effective way to upgrade your app? Consider using a cool animation. Flutter renders everything on the screen relying on Skia graphics library, so you can animate literally anything.

    Written by Sherif Adel
    Last Updated: 2/14/2024
    6 min
    Guide to Flutter Implicit Animations
    TL;DR

    A comprehensive tutorial on implementing animations in Flutter, covering implicit and explicit animations, Tween, AnimationController, and Hero transitions. Build polished mobile apps with Evolvice's nearshore Flutter developers.

    Looking for an effective way to upgrade your app? Consider using a cool animation. Flutter renders everything on the screen relying on Skia graphics library, instead of using those pesky native views. Therefore, you can animate literally anything. In this tutorial, you will learn how to implement basic animations in Flutter.

    Implicit Animations

    Flutter includes a series of widgets that are animated versions of existing widgets that you've probably already used in your app. For instance:

    • Container → AnimatedContainer
    • Positioned → AnimatedPositioned
    • Opacity → AnimatedOpacity

    These widgets automatically animate changes to their properties. They extend ImplicitlyAnimatedWidget—that's why these animations, in general, are called Implicit animations.

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        body: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.center,
              child: AnimatedContainer(
                duration: Duration(milliseconds: 300),
                width: 200,
                height: 100,
                color: Colors.blue,
              ),
            ),
          ],
        ),
      );
    }

    Although implicit animated widgets are easy to use, they have some disadvantages. Most important—you don't have full control of these animations, so it is not possible to implement repeating animation or listen to the animation state and react to the changes.

    Practice: Building a Drawer Menu

    Let's look a little closer at how you can use one of those widgets to implement animations in your app.

    In this app, we have a typical structure: AppBar, home page and a drawer (side menu). For this sample we will implement drawer by ourselves, instead of using drawer property in Scaffold widget.

    class App extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Home(),
        );
      }
    }
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      var isShownMenu = false;
    
      @override
      Widget build(BuildContext context) {
        final width = MediaQuery.of(context).size.width * 0.65;
        final height = MediaQuery.of(context).size.height;
    
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.blue,
            title: Text("Home"),
            leading: IconButton(
              icon: Icon(Icons.menu),
              onPressed: () {
                setState(() {
                  isShownMenu = !isShownMenu;
                });
              },
            ),
          ),
          body: Stack(
            children: [
              MainPage(),
              Positioned(
                width: width,
                height: height,
                left: isShownMenu ? 0 : -width,
                top: 0,
                child: Container(
                  width: width,
                  color: Colors.redAccent,
                  height: double.infinity,
                ),
              ),
            ],
          ),
        );
      }
    }

    You can see AppBar here with IconButton for opening menu. Body of the Scaffold consists of Stack with MainPage and our drawer. Its visibility is controlled by setting negative left when hidden and zero left when visible. MainPage is a simple Container with Text widget, it is omitted for brevity. There are no animations for now and drawer opening looks a little clunky.

    Using AnimatedPositioned

    We can add a simple animation by replacing Positioned with AnimatedPositioned. Let's check the code.

    @override
    Widget build(BuildContext context) {
      // ...
      body: Stack(
        children: [
          MainPage(),
          _buildAnimatedMenu(width, height),
        ],
      ),
    }
    
    Widget _buildAnimatedMenu(double width, double height) {
      return AnimatedPositioned(
        duration: Duration(milliseconds: 300),
        width: width,
        height: height,
        left: isShownMenu ? 0 : -width,
        top: 0,
        child: MainMenu(
          width: width,
        ),
      );
    }

    Same as AnimatedContainer, AnimatedPositioned widget will animate any changes to its properties and this is exactly what we need. By setting only one additional property—duration, which defines how long animation will run, we added animation to the drawer opening.

    Adding Background Dimming with AnimatedOpacity

    Usually, drawer menu should dim what is behind it. You can implement such behavior in many ways, but we will use AnimatedOpacity in this case.

    @override
    Widget build(BuildContext context) {
      // ...
      body: Stack(
        children: [
          MainPage(),
          _buildBackgroundSkim(),
          _buildAnimatedMenu(width, height),
        ],
      ),
    }
    
    Widget _buildBackgroundSkim() {
      return AnimatedOpacity(
        duration: Duration(milliseconds: 300),
        opacity: isShownMenu ? 1 : 0,
        child: Container(
          color: Color.fromARGB(42, 0, 0, 0),
        ),
      );
    }

    New function returns AnimatedOpacity widget with the same duration as our previous animation. Property opacity is set to 1 if menu is visible and to 0 if not. Child of this widget is a simple Container with transparent grey background.

    Adding Curves

    Animations in all animated widgets are constant by default, they are changing their values in a linear way. Changing the curves is as easy as setting another property in the constructor. Look at the code below.

    Widget _buildAnimatedMenu(double width, double height) {
      return AnimatedPositioned(
        duration: Duration(milliseconds: 300),
        width: width,
        height: height,
        left: isShownMenu ? 0 : -width,
        top: 0,
        curve: isShownMenu ? Curves.bounceOut : Curves.linear,
        child: MainMenu(
          width: width,
        ),
      );
    }

    Linear curve is set if the menu is shown, so next animation (dismissing the menu) will be linear, otherwise bounceOut is set. All possible predefined curves can be found in the Flutter documentation.

    Conclusion

    Using Implicit Animated Widgets is the most straightforward way to implement basic animations in Flutter. But keep in mind, that basic animation is the one which doesn't repeat forever and it is only for one widget. If you want to implement custom animations check AnimatedWidget and AnimatedBuilder.

    Meet the Team

    Sherif Adel

    Sherif Adel

    Author

    Amira Adel

    Amira Adel

    Editor

    Need Flutter developers for your mobile app?

    Hire Flutter Experts

    Frequently Asked Questions

    What are implicit animations in Flutter?

    Implicit animations are widgets that automatically animate changes to their properties. They extend ImplicitlyAnimatedWidget and include widgets like AnimatedContainer, AnimatedPositioned, and AnimatedOpacity.

    How do I add animation duration in Flutter?

    Simply set the duration property on any implicit animated widget. For example: AnimatedPositioned(duration: Duration(milliseconds: 300), ...) will create a 300ms animation.

    What are the limitations of implicit animations?

    You don't have full control of implicit animations—it's not possible to implement repeating animations or listen to the animation state and react to changes. For more control, use AnimatedWidget or AnimatedBuilder.

    How do I change animation curves in Flutter?

    Set the curve property on implicit animated widgets. Flutter provides predefined curves like Curves.bounceOut, Curves.linear, Curves.easeIn, and many more.

    How do I create a drawer animation in Flutter?

    Use AnimatedPositioned to slide the drawer in and out by changing the left property. Combine with AnimatedOpacity to dim the background when the drawer is open.

    Related Posts

    Recommended Expertise

    Explore related topics from the Evolvice knowledge base