Receber por email
← Voltar para o catálogo

flutter-animations

Comprehensive guide for implementing animations in Flutter. Use when adding motion and visual effects to Flutter apps: implicit animations (AnimatedContainer, AnimatedOpacity, TweenAnimationBuilder), explicit animations (AnimationController, Tween, AnimatedWidget/AnimatedBuilder), hero animations (shared element transitions), staggered animations (sequential/overlapping), and physics-based animati

367estrelas
Atualizado há 4 meses

Ver no GitHub ↗

Como adicionar

/plugin marketplace add aiskillstore/marketplace

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/flutter-animations/svg)](https://www.skillteca.com.br/skills/flutter-animations)
#ai

Skills relacionadas

Ver todas de Segurança →

Alerta por categoria

Receba novas skills de Segurança toda segunda

1 email curto, só com as skills novas de Segurança. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Flutter Animations

Overview

Create smooth, performant animations in Flutter using the right approach for each use case. This skill covers complete animation workflow: from choosing between implicit/explicit approaches to implementing complex effects like hero transitions and staggered animations.

Animation Type Decision Tree

Choose the right animation type based on your requirements:

Implicit Animations - Use when:

  • Animating a single property (color, size, position)
  • Animation is triggered by state change
  • No need for fine-grained control

Explicit Animations - Use when:

  • Need full control over animation lifecycle
  • Animating multiple properties simultaneously
  • Need to react to animation state changes
  • Creating custom animations or transitions

Hero Animations - Use when:

  • Sharing an element between two screens
  • Creating shared element transitions
  • User expects element to "fly" between routes

Staggered Animations - Use when:

  • Multiple animations should run sequentially or overlap
  • Creating ripple effects or sequential reveals
  • Animating list items in sequence

Physics-Based Animations - Use when:

  • Animations should feel natural/physical
  • Spring-like behavior, scrolling gestures
  • Draggable interactions

Implicit Animations

Implicit animations automatically handle the animation when properties change. No controller needed.

Common Implicit Widgets

AnimatedContainer - Animates multiple properties (size, color, decoration, padding):

AnimatedContainer(
  duration: const Duration(milliseconds: 300),
  curve: Curves.easeInOut,
  width: _expanded ? 200 : 100,
  height: _expanded ? 200 : 100,
  color: _expanded ? Colors.blue : Colors.red,
  child: const FlutterLogo(),
)

AnimatedOpacity - Simple fade animation:

AnimatedOpacity(
  opacity: _visible ? 1.0 : 0.0,
  duration: const Duration(milliseconds: 300),
  child: const Text('Hello'),
)

TweenAnimationBuilder - Custom tween animation without boilerplate:

TweenAnimationBuilder<double>(
  tween: Tween<double>(begin: 0, end: 1),
  duration: const Duration(seconds: 1),
  builder: (context, value, child) {
    return Opacity(
      opacity: value,
      child: Transform.scale(
        scale: value,
        child: child,
      ),
    );
  },
  child: const FlutterLogo(),
)

Other implicit widgets:

  • AnimatedPadding - Padding animation
  • AnimatedPositioned - Position animation (in Stack)
  • AnimatedAlign - Alignment animation
  • AnimatedContainer - Multiple properties
  • AnimatedSwitcher - Cross-fade between widgets
  • AnimatedDefaultTextStyle - Text style animation

Best Practices

  • Prefer implicit animations for simple cases
  • Use appropriate curves for natural motion (see Curves class)
  • Set curve and duration for predictable behavior
  • Use onEnd callback when needed
  • Avoid nested implicit animations for performance

Explicit Animations

Explicit animations provide full control with AnimationController.

Core Components

AnimationController - Drives the animation:

late AnimationController _controller;

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

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

Tween - Interpolates between begin and end values:

animation = Tween<double>(begin: 0, end: 300).animate(_controller);

CurvedAnimation - Applies a curve to the animation:

animation = CurvedAnimation(
  parent: _controller,
  curve: Curves.easeInOut,
);

AnimatedWidget Pattern

Best for reusable animated widgets:

class AnimatedLogo extends AnimatedWidget {
  const AnimatedLogo({super.key, required Animation<double> animation})
    : super(listenable: animation);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Center(
      child: Container(
        height: animation.value,
        width: animation.value,
        child: const FlutterLogo(),
      ),
    );
  }
}

AnimatedBuilder Pattern

Best for complex widgets with animations:

class GrowTransition extends StatelessWidget {
  const GrowTransition({
    required this.child,
    required this.animation,
    super.key,
  });

  final Widget child;
  final Animation<double> animation;

  @override
  Widget build(BuildContext context) {
    return Center(
      child: AnimatedBuilder(
        animation: animation,
        builder: (context, child) {
          return SizedBox(
            height: animation.value,
            width: animation.value,
            child: child,
          );
        },
        child: child,
      ),
    );
  }
}

Monitoring Animation State

animation.addStatusListener((status) {
  switch (status) {
    case AnimationStatus.completed:
      _controller.reverse();
      break;
    case AnimationStatus.dismissed:
      _controller.forward();
      break;
    default:
      break;
  }
});

Multiple Simultaneous Animations

class AnimatedLogo extends AnimatedWidget {
  const AnimatedLogo({super.key, required Animation<double> animation})
    : super(listenable: animation);

  static final _opacityTween = Tween<double>(begin: 0.1, end: 1);
  static final _sizeTween = Tween<double>(begin: 0, end: 300);

  @override
  Widget build(BuildContext context) {
    final animation = listenable as Animation<double>;
    return Center(
      child: Opacity(
        opacity: _opacityTween.evaluate(animation),
        child: Container(
          height: _sizeTween.evaluate(animation),
          width: _sizeTween.evaluate(animation),
          child: const FlutterLogo(),
        ),
      ),
    );
  }
}

Built-in Explicit Transitions

Flutter provides ready-to-use transitions:

  • FadeTransition - Fade animation
  • ScaleTransition - Scale animation
  • SlideTransition - Slide animation
  • SizeTransition - Size animation
  • RotationTransition - Rotation animation
  • PositionedTransition - Position animation (in Stack)

Example:

FadeTransition(
  opacity: _animation,
  child: const FlutterLogo(),
)

Performance Tips

  • Dispose controllers when widget is removed
  • Use AnimatedBuilder for optimal rebuilds
  • Avoid setState() in animation listeners (use AnimatedWidget/AnimatedBuilder)
  • Use timeDilation to slow animations during debugging

Hero Animations

Hero animations create shared element transitions between screens.

Basic Hero Animation

Source screen:

Hero(
  tag: 'hero-image',
  child: Image.asset('images/logo.png'),
)

Destination screen:

Hero(
  tag: 'hero-image',  // Same tag!
  child: Image.asset('images/logo.png'),
)

Complete Example

class PhotoHero extends StatelessWidget {
  const PhotoHero({
    super.key,
    required this.photo,
    this.onTap,
    required this.width,
  });

  final String photo;
  final VoidCallback? onTap;
  final double width;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      child: Hero(
        tag: photo,
        child: Material(
          color: Colors.transparent,
          child: InkWell(
            onTap: onTap,
            child: Image.asset(photo, fit: BoxFit.contain),
          ),
        ),
      ),
    );
  }
}

Navigating between screens:

Navigator.of(context).push(
  MaterialPageRoute<void>(
    builder: (context) {
      return Scaffold(
        appBar: AppBar(title: const Text('Detail')),
        body: Center(
          child: PhotoHero(
            photo: 'images/logo.png',
            width: 300.0,
            onTap: () => Navigator.of(context).pop(),
          ),
        ),
      );
    },
  ),
);

Radial Hero Animation

Transform from circle to rectangle during transition:

class RadialExpansi
Compartilhar X LinkedIn