Flutter Animations

Flutter Animations

Automate and integrate Flutter Animations for smooth and dynamic mobile app motion design

Category: productivity Source: madteacher/mad-agents-skills

Flutter Animations is a community skill for creating fluid animations in Flutter applications, covering implicit animations, explicit controllers, hero transitions, staggered sequences, and custom painters for rich motion design.

What Is This?

Overview

Flutter Animations provides patterns for building smooth, performant animations in Flutter applications. It covers implicit animations using AnimatedContainer, AnimatedOpacity, and similar widgets for simple property transitions, explicit animation controllers with Tween, CurvedAnimation, and AnimationBuilder for precise timing control, hero transitions for shared element animation between screens during navigation, staggered animation sequences using Interval curves for orchestrated multi-element choreography, and custom painter animations for drawing-based motion effects like progress indicators and wave forms. The skill enables developers to implement polished motion design that enhances user experience without compromising frame rate.

Who Should Use This

This skill serves Flutter developers adding motion to application interfaces, designers implementing micro-interactions and page transitions, and teams building custom animated components that go beyond default widget transitions.

Why Use It?

Problems It Solves

Choosing between implicit and explicit animation approaches requires understanding trade-offs between simplicity and control. Orchestrating multiple animations that start at different times needs stagger patterns. Achieving smooth 60fps animations demands proper lifecycle management of animation controllers. Custom drawing animations require combining CustomPainter with animation tickers.

Core Highlights

Implicit widgets animate property changes automatically without controller management. Explicit controllers provide frame-level control over timing, duration, and curve selection. Hero system creates shared element transitions across route navigation. Stagger builder sequences multiple animations with offset timing.

How to Use It?

Basic Usage

import 'package:flutter/material.dart';

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

  @override
  State<AnimatedCard> createState()
    => _AnimatedCardState();
}

class _AnimatedCardState
    extends State<AnimatedCard> {
  bool _expanded = false;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => setState(
        () => _expanded = !_expanded),
      child: AnimatedContainer(
        duration: const Duration(
          milliseconds: 400),
        curve: Curves.easeInOut,
        width: _expanded ? 300 : 150,
        height: _expanded ? 200 : 100,
        decoration: BoxDecoration(
          color: _expanded
            ? Colors.blue
            : Colors.grey,
          borderRadius:
            BorderRadius.circular(
              _expanded ? 16 : 8),
        ),
        child: AnimatedOpacity(
          opacity:
            _expanded ? 1.0 : 0.5,
          duration: const Duration(
            milliseconds: 300),
          child: const Center(
            child: Text('Tap me')),
        ),
      ),
    );
  }
}

Real-World Examples

import 'package:flutter/material.dart';

class StaggeredList extends
    StatefulWidget {
  final List<String> items;
  const StaggeredList({
    super.key,
    required this.items,
  });

  @override
  State<StaggeredList> createState()
    => _StaggeredListState();
}

class _StaggeredListState
    extends State<StaggeredList>
    with SingleTickerProviderStateMixin {
  late AnimationController _ctrl;

  @override
  void initState() {
    super.initState();
    _ctrl = AnimationController(
      vsync: this,
      duration: Duration(
        milliseconds:
          widget.items.length * 150),
    )..forward();
  }

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

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: widget.items.length,
      itemBuilder: (ctx, i) {
        final start =
          i / widget.items.length;
        final end = (i + 1) /
          widget.items.length;
        final anim = CurvedAnimation(
          parent: _ctrl,
          curve: Interval(
            start, end,
            curve: Curves.easeOut),
        );
        return FadeTransition(
          opacity: anim,
          child: SlideTransition(
            position: Tween(
              begin:
                const Offset(0.3, 0),
              end: Offset.zero,
            ).animate(anim),
            child: ListTile(
              title: Text(
                widget.items[i])),
          ),
        );
      },
    );
  }
}

Advanced Tips

Use RepaintBoundary around animated widgets to isolate repaint regions and improve rendering performance. Prefer implicit animations for simple state-driven transitions and reserve explicit controllers for complex choreography. Use the AnimationController status listener to chain sequential animations.

When to Use It?

Use Cases

Build a product showcase with hero transitions between list and detail views. Create a loading screen with staggered dot animations and wave effects. Implement a settings panel with animated expand and collapse sections.

Related Topics

Flutter animation framework, motion design, widget transitions, custom painters, and performance optimization.

Important Notes

Requirements

Flutter SDK with the animation framework included. Understanding of StatefulWidget lifecycle for controller management. TickerProviderStateMixin for explicit animation controllers.

Usage Recommendations

Do: dispose animation controllers in the dispose method to prevent memory leaks. Use const constructors for non-animated child widgets to avoid unnecessary rebuilds. Test animations at different device frame rates to verify smoothness.

Don't: create animation controllers in the build method which causes new controllers every rebuild. Animate properties that trigger full layout recalculations when transform-based animations suffice. Use excessively long animation durations that delay user interaction.

Limitations

Complex animation sequences with many controllers add widget tree complexity. Custom painter animations require lower-level canvas API knowledge. Animations that trigger layout rebuilds every frame can drop below 60fps on older devices.