Flutter Animations and Transitions: A Complete Guide

Flutter Animations and Transitions

What Are Animations?

Animations make things move on your screen. When you open an app and see a button grow bigger, or when a picture slides from one side to another, that is animation. Animations make apps fun to use and easy to understand.

Why Do We Need Animations?

Animations help users in many ways:

  • They show that something is happening
  • They guide users where to look
  • They make apps feel alive and friendly
  • They help users understand what changed on the screen

Types of Animations in Flutter

1. Implicit Animations

Implicit animations are the easiest animations to make. You just tell Flutter what you want to change, and Flutter does all the work.

AnimatedContainer is the most popular implicit animation. It can change size, color, shape, and position smoothly.

AnimatedContainer(
  duration: Duration(seconds: 1),
  width: isExpanded ? 200 : 100,
  height: isExpanded ? 200 : 100,
  color: isExpanded ? Colors.blue : Colors.red,
  child: Text('Hello'),
)

AnimatedOpacity makes things appear and disappear slowly.

AnimatedOpacity(
  opacity: isVisible ? 1.0 : 0.0,
  duration: Duration(seconds: 1),
  child: Text('I fade in and out'),
)

AnimatedPositioned moves widgets around inside a Stack.

AnimatedPositioned(
  duration: Duration(seconds: 1),
  left: isMoved ? 100 : 0,
  top: isMoved ? 100 : 0,
  child: Container(width: 50, height: 50, color: Colors.green),
)

Other implicit animations include:

  • AnimatedAlign
  • AnimatedPadding
  • AnimatedRotation
  • AnimatedScale
  • AnimatedSize

2. Explicit Animations

Explicit animations give you more control. You control when the animation starts, stops, and how fast it goes. You need an AnimationController to use explicit animations.

AnimationController is like a remote control for your animation.

class MyWidget extends StatefulWidget {
  @override
  _MyWidgetState createState() => _MyWidgetState();
}

class _MyWidgetState extends State<MyWidget> with SingleTickerProviderStateMixin {
  late AnimationController controller;
  
  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      duration: Duration(seconds: 2),
      vsync: this,
    );
    controller.forward(); // Start the animation
  }
  
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

RotationTransition spins widgets around.

RotationTransition(
  turns: controller,
  child: Icon(Icons.star, size: 100),
)

ScaleTransition makes things bigger or smaller.

ScaleTransition(
  scale: controller,
  child: Container(width: 100, height: 100, color: Colors.purple),
)

SlideTransition slides widgets in and out.

SlideTransition(
  position: Tween<Offset>(
    begin: Offset(-1, 0),
    end: Offset.zero,
  ).animate(controller),
  child: Text('I slide in from left'),
)

3. Hero Animations

Hero animations make widgets fly from one screen to another screen. When you tap on a picture and it grows to fill the next screen, that is a hero animation.

// On first screen
Hero(
  tag: 'myHero',
  child: Image.network('https://example.com/image.jpg'),
)

// On second screen
Hero(
  tag: 'myHero',
  child: Image.network('https://example.com/image.jpg'),
)

The tag must be the same on both screens.

Animation Curves

Curves make animations feel more natural. Instead of moving at the same speed all the time, curves make animations speed up or slow down.

Common curves:

  • Curves.linear – Same speed from start to end
  • Curves.easeIn – Starts slow, then speeds up
  • Curves.easeOut – Starts fast, then slows down
  • Curves.easeInOut – Starts slow, speeds up in middle, slows down at end
  • Curves.bounceOut – Bounces at the end
  • Curves.elasticOut – Springs back and forth at the end
AnimatedContainer(
  duration: Duration(seconds: 1),
  curve: Curves.bounceOut,
  width: 200,
  height: 200,
)

Tween Animations

Tween tells Flutter to change from one value to another value. You can tween numbers, colors, sizes, and positions.

Animation<double> animation = Tween<double>(
  begin: 0.0,
  end: 300.0,
).animate(controller);

// For colors
Animation<Color?> colorAnimation = ColorTween(
  begin: Colors.red,
  end: Colors.blue,
).animate(controller);

Page Transitions

Page transitions control how one screen changes to another screen.

Navigator.push(
  context,
  PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => SecondPage(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return FadeTransition(
        opacity: animation,
        child: child,
      );
    },
  ),
);

You can create different types of transitions:

  • Fade transition
  • Slide transition
  • Scale transition
  • Rotation transition

Staggered Animations

Staggered animations run multiple animations at different times but use the same controller.

final Animation<double> opacity = Tween<double>(
  begin: 0.0,
  end: 1.0,
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(0.0, 0.5, curve: Curves.ease),
  ),
);

final Animation<double> size = Tween<double>(
  begin: 0.0,
  end: 200.0,
).animate(
  CurvedAnimation(
    parent: controller,
    curve: Interval(0.5, 1.0, curve: Curves.ease),
  ),
);

Physics-Based Animations

These animations follow real physics rules, like gravity and friction.

controller.animateWith(
  SpringSimulation(
    SpringDescription(
      mass: 1,
      stiffness: 100,
      damping: 10,
    ),
    0,
    1,
    0,
  ),
);

Tips for Good Animations

  1. Keep animations short – Most animations should be between 200 and 500 milliseconds
  2. Don’t animate too many things – Too many animations confuse users
  3. Use the right curve – Choose curves that feel natural
  4. Always dispose controllers – This saves memory
  5. Test on real devices – Animations may run slower on older phones
  6. Use implicit animations when possible – They are easier to write

Common Mistakes to Avoid

  • Forgetting to dispose AnimationController
  • Not using vsync with TickerProvider
  • Making animations too slow or too fast
  • Animating too many widgets at once
  • Not testing animations on different devices

Performance Tips

  • Use const constructors when possible
  • Avoid rebuilding entire widget trees
  • Use RepaintBoundary for complex animations
  • Keep animations simple on lists
  • Use AnimatedBuilder to rebuild only necessary parts

Conclusion

Animations make Flutter apps beautiful and easy to use. Start with simple implicit animations, then learn explicit animations when you need more control. Practice with different types of animations to see what works best for your app. Remember to keep animations smooth, fast, and helpful for users.

Leave a Reply

Your email address will not be published. Required fields are marked *