Thuan Nguyen
Thuan Nguyen

Love sweet potatoes

Flutter animations with Animated Builder

Flutter animations with Animated Builder

We can implement animations with controller and animation widget, but there is better way to implement animation which allow you to create a complex animations that requires a widget and builder function. In this post, I will show you how to implement an animation in Flutter using Animated Builder

  1. First create an animation controller to control animation duration
    1
    
    AnimationController? _controller;
    
  2. And create an animation widget
    1
    
    Animation<Size>? _heightAnimation;
    
  3. Add Ticker Provider mixin to your stateful widget
    1
    
    with SingleTickerProviderStateMixin
    
  4. Initialize animation
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    
    @override
    void initState() {
     supper.initState();
    
     _controller = AnimationController(
         vsync: this,
         duration: const Duration(
             milliseconds: 300,
         ),
     );
    
     // attach controller to animation
     _heightAnimation = Tween<Size>(
         begin: const Size(
             double.infinity,
             260,
         ),
         end: const Size(
             double.infinity,
             320,
         ),
     ).animate(CurveAnimation(
         parent: _controller,
         curve: Curves.linear,
     ));
    
     // we do not need to listen state anymore
     // _heightAnimation?.addListener(() {
     //     setState(() {});
     // });
    }
    
  5. Use in your widget
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    @override
      Widget build(BuildContext context) {
     return AnimatedBuilder(
       animation: _controller,
       child: Container( // prebuilt child will not rebuild on every animation tick
         width: 200.0,
         height: 200.0,
         color: Colors.red,
         child: const Center(
           child: Text('Hello World!'),
         ),
       ),
       builder: (BuildContext context, Widget? child) {
         return Container(
           height: _heightAnimation.value.height,
           color: Colors.blue,
           child: child,
         );
       },
     );
      }
    }
    

Animated Builder is not limited to Animations, any subtype of Listenable (ChangeNotifier and ValueNotifier) can use with an AnimationBuilder to rebuild only specific widgets leaving others untouched.

  1. trigger animation
    1
    2
    3
    
    _controller?.forward();
    // or
    _controller?.reverse();
    
  2. remember to dispose animation to prevent memory leak
    1
    2
    3
    4
    5
    
    @override
    void dispose() {
     super.dispose();
     _controller?.dispose();
    }
    

It’s more efficient to build a subtree once instead of rebuilding it on every animation tick. Using prebuilt child can improve performance significantly in some cases and is therefore a good practice.