0
0
FlutterHow-ToBeginner · 3 min read

How to Use AnimationController in Flutter: Simple Guide

Use AnimationController in Flutter by creating it inside a StatefulWidget with a TickerProvider, then start, stop, or reverse the animation using its methods. It controls animation timing and requires disposing to free resources.
📐

Syntax

The AnimationController requires a vsync parameter, usually provided by a TickerProvider like SingleTickerProviderStateMixin. You create it with a duration and control the animation with methods like forward(), reverse(), and stop().

  • vsync: Prevents offscreen animations from consuming resources.
  • duration: Length of the animation.
  • forward(): Starts the animation forward.
  • reverse(): Runs the animation backward.
  • dispose(): Frees resources when done.
dart
class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

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

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}
💻

Example

This example shows a square that grows and shrinks repeatedly using AnimationController. The controller drives the size animation and updates the UI with AnimatedBuilder.

dart
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: AnimationDemo());
  }
}

class AnimationDemo extends StatefulWidget {
  const AnimationDemo({super.key});

  @override
  State<AnimationDemo> createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
      lowerBound: 50.0,
      upperBound: 200.0,
    )..repeat(reverse: true);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('AnimationController Example')),
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Container(
              width: _controller.value,
              height: _controller.value,
              color: Colors.blue,
            );
          },
        ),
      ),
    );
  }
}
Output
A blue square in the center of the screen smoothly grows from 50x50 to 200x200 pixels and then shrinks back repeatedly.
⚠️

Common Pitfalls

  • Not disposing the AnimationController causes memory leaks.
  • Forgetting to add with SingleTickerProviderStateMixin to your state class leads to errors.
  • Using AnimationController outside a StatefulWidget or without vsync causes performance issues.
  • Not calling setState or using AnimatedBuilder means UI won't update with animation.
dart
/* Wrong: Missing dispose */
class _WrongState extends State<MyWidget> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

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

  // Missing dispose method
}

/* Right: Proper dispose */
@override
void dispose() {
  _controller.dispose();
  super.dispose();
}
📊

Quick Reference

  • AnimationController(vsync, duration): Creates the controller.
  • forward(): Starts animation forward.
  • reverse(): Runs animation backward.
  • repeat(reverse: true): Loops animation back and forth.
  • dispose(): Clean up controller.

Key Takeaways

Always create AnimationController inside a StatefulWidget with SingleTickerProviderStateMixin for vsync.
Dispose the AnimationController in the dispose() method to avoid memory leaks.
Use methods like forward(), reverse(), and repeat() to control animation playback.
Use AnimatedBuilder or setState to update the UI when the animation value changes.
AnimationController controls timing but needs a widget to show the animation visually.