Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Implement Flutter animations: implicit, explicit, hero, staggered, and physics-based with a decision tree guide.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
assets/templates/staggered_animation.dart
1import 'package:flutter/material.dart';23/// Staggered animation example with multiple property animations4///5/// This example demonstrates:6/// - Single AnimationController driving multiple animations7/// - Interval-based timing for sequential/overlapping animations8/// - Multiple tweens for different properties9/// - Status monitoring for animation loops1011void main() => runApp(const StaggeredAnimationApp());1213class StaggeredAnimationApp extends StatelessWidget {14const StaggeredAnimationApp({super.key});1516@override17Widget build(BuildContext context) {18return MaterialApp(19title: 'Staggered Animation',20theme: ThemeData(21colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),22),23home: const StaggeredDemo(),24);25}26}2728/// Staggered animation with fade, scale, and color changes29class StaggeredAnimation extends StatelessWidget {30StaggeredAnimation({super.key, required this.animation});3132late final Animation<double> opacity = Tween<double>(begin: 0.0, end: 1.0)33.animate(34CurvedAnimation(35parent: animation,36curve: const Interval(0.0, 0.1, curve: Curves.ease),37),38);3940late final Animation<double> width = Tween<double>(begin: 50.0, end: 150.0)41.animate(42CurvedAnimation(43parent: animation,44curve: const Interval(0.125, 0.25, curve: Curves.ease),45),46);4748late final Animation<double> height = Tween<double>(begin: 50.0, end: 150.0)49.animate(50CurvedAnimation(51parent: animation,52curve: const Interval(0.25, 0.375, curve: Curves.ease),53),54);5556late final Animation<BorderRadius?> borderRadius =57BorderRadiusTween(58begin: BorderRadius.circular(4),59end: BorderRadius.circular(75),60).animate(61CurvedAnimation(62parent: animation,63curve: const Interval(0.375, 0.5, curve: Curves.ease),64),65);6667late final Animation<Color?> color =68ColorTween(begin: Colors.red, end: Colors.orange).animate(69CurvedAnimation(70parent: animation,71curve: const Interval(0.5, 0.625, curve: Curves.ease),72),73);7475final Animation<double> animation;7677Widget _buildAnimation(BuildContext context, Widget? child) {78return Center(79child: Opacity(80opacity: opacity.value,81child: Container(82width: width.value,83height: height.value,84decoration: BoxDecoration(85color: color.value,86border: Border.all(color: Colors.indigo[300]!, width: 3),87borderRadius: borderRadius.value,88),89),90),91);92}9394@override95Widget build(BuildContext context) {96return AnimatedBuilder(animation: animation, builder: _buildAnimation);97}98}99100class StaggeredDemo extends StatefulWidget {101const StaggeredDemo({super.key});102103@override104State<StaggeredDemo> createState() => _StaggeredDemoState();105}106107class _StaggeredDemoState extends State<StaggeredDemo>108with SingleTickerProviderStateMixin {109late AnimationController _controller;110111@override112void initState() {113super.initState();114_controller = AnimationController(115duration: const Duration(milliseconds: 2000),116vsync: this,117);118}119120Future<void> _playAnimation() async {121try {122await _controller.forward().orCancel;123await _controller.reverse().orCancel;124} on TickerCanceled {125// Animation was canceled126}127}128129@override130void dispose() {131_controller.dispose();132super.dispose();133}134135@override136Widget build(BuildContext context) {137return Scaffold(138appBar: AppBar(title: const Text('Staggered Animation')),139body: GestureDetector(140behavior: HitTestBehavior.opaque,141onTap: _playAnimation,142child: Center(143child: Container(144width: 300,145height: 300,146decoration: BoxDecoration(147color: Colors.black.withValues(alpha: 0.1),148border: Border.all(color: Colors.black.withValues(alpha: 0.5)),149),150child: StaggeredAnimation(animation: _controller.view),151),152),153),154);155}156}157158/// Staggered menu animation example159class StaggeredMenuExample extends StatefulWidget {160const StaggeredMenuExample({super.key});161162@override163State<StaggeredMenuExample> createState() => _StaggeredMenuExampleState();164}165166class _StaggeredMenuExampleState extends State<StaggeredMenuExample>167with SingleTickerProviderStateMixin {168static const _menuTitles = [169'Declarative Style',170'Premade Widgets',171'Stateful Hot Reload',172'Native Performance',173'Great Community',174];175176static const _initialDelayTime = Duration(milliseconds: 50);177static const _itemSlideTime = Duration(milliseconds: 250);178static const _staggerTime = Duration(milliseconds: 50);179180late AnimationController _controller;181182final _animationDuration =183_initialDelayTime + (_staggerTime * _menuTitles.length) + _itemSlideTime;184185@override186void initState() {187super.initState();188_controller = AnimationController(189duration: _animationDuration,190vsync: this,191);192_controller.forward();193}194195@override196void dispose() {197_controller.dispose();198super.dispose();199}200201@override202Widget build(BuildContext context) {203return Scaffold(204appBar: AppBar(title: const Text('Staggered Menu')),205body: ListView.builder(206itemCount: _menuTitles.length,207itemBuilder: (context, index) {208final start =209_initialDelayTime.inMilliseconds.toDouble() +210(_staggerTime.inMilliseconds.toDouble() * index);211final end = start + _itemSlideTime.inMilliseconds.toDouble();212final intervalStart =213start / _animationDuration.inMilliseconds.toDouble();214final intervalEnd =215end / _animationDuration.inMilliseconds.toDouble();216217final animation = CurvedAnimation(218parent: _controller,219curve: Interval(intervalStart, intervalEnd, curve: Curves.easeOut),220);221222return AnimatedBuilder(223animation: _controller,224builder: (context, child) {225return SlideTransition(226position: Tween<Offset>(227begin: const Offset(1, 0),228end: Offset.zero,229).animate(animation),230child: FadeTransition(opacity: animation, child: child),231);232},233child: ListTile(title: Text(_menuTitles[index])),234);235},236),237);238}239}240