Flutter Animations
Automate and integrate Flutter Animations for smooth and dynamic mobile app motion design
Category: productivity Source: madteacher/mad-agents-skillsFlutter 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.