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/explicit_animation.dart
1import 'package:flutter/material.dart';23/// Explicit animation example using AnimationController4///5/// This example demonstrates:6/// - AnimationController setup and lifecycle7/// - Tween interpolation8/// - AnimatedWidget pattern for reusable animations9/// - AnimatedBuilder pattern for complex widgets10/// - Animation status monitoring1112void main() => runApp(const ExplicitAnimationApp());1314class ExplicitAnimationApp extends StatelessWidget {15const ExplicitAnimationApp({super.key});1617@override18Widget build(BuildContext context) {19return MaterialApp(20title: 'Explicit Animation',21theme: ThemeData(22colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),23),24home: const LogoAnimationDemo(),25);26}27}2829/// Basic explicit animation with addListener and setState30class BasicExplicitAnimation extends StatefulWidget {31const BasicExplicitAnimation({super.key});3233@override34State<BasicExplicitAnimation> createState() => _BasicExplicitAnimationState();35}3637class _BasicExplicitAnimationState extends State<BasicExplicitAnimation>38with SingleTickerProviderStateMixin {39late AnimationController _controller;40late Animation<double> _animation;4142@override43void initState() {44super.initState();45_controller = AnimationController(46duration: const Duration(seconds: 2),47vsync: this,48);4950_animation = Tween<double>(begin: 0, end: 300).animate(_controller)51..addListener(() {52setState(() {});53});5455_controller.forward();56}5758@override59void dispose() {60_controller.dispose();61super.dispose();62}6364@override65Widget build(BuildContext context) {66return Scaffold(67appBar: AppBar(title: const Text('Basic Explicit')),68body: Center(69child: Container(70margin: const EdgeInsets.symmetric(vertical: 10),71height: _animation.value,72width: _animation.value,73child: const FlutterLogo(),74),75),76);77}78}7980/// AnimatedWidget pattern - best for reusable animated widgets81class AnimatedLogo extends AnimatedWidget {82const AnimatedLogo({super.key, required Animation<double> animation})83: super(listenable: animation);8485@override86Widget build(BuildContext context) {87final animation = listenable as Animation<double>;88return Center(89child: Container(90margin: const EdgeInsets.symmetric(vertical: 10),91height: animation.value,92width: animation.value,93child: const FlutterLogo(),94),95);96}97}9899class AnimatedWidgetDemo extends StatefulWidget {100const AnimatedWidgetDemo({super.key});101102@override103State<AnimatedWidgetDemo> createState() => _AnimatedWidgetDemoState();104}105106class _AnimatedWidgetDemoState extends State<AnimatedWidgetDemo>107with SingleTickerProviderStateMixin {108late AnimationController _controller;109late Animation<double> _animation;110111@override112void initState() {113super.initState();114_controller = AnimationController(115duration: const Duration(seconds: 2),116vsync: this,117);118119_animation = Tween<double>(begin: 0, end: 300).animate(_controller);120_controller.forward();121}122123@override124void dispose() {125_controller.dispose();126super.dispose();127}128129@override130Widget build(BuildContext context) {131return Scaffold(132appBar: AppBar(title: const Text('Animated Widget')),133body: AnimatedLogo(animation: _animation),134);135}136}137138/// AnimatedBuilder pattern - best for complex widgets139class LogoWidget extends StatelessWidget {140const LogoWidget({super.key});141142@override143Widget build(BuildContext context) {144return Container(145margin: const EdgeInsets.symmetric(vertical: 10),146child: const FlutterLogo(),147);148}149}150151class GrowTransition extends StatelessWidget {152const GrowTransition({153required this.child,154required this.animation,155super.key,156});157158final Widget child;159final Animation<double> animation;160161@override162Widget build(BuildContext context) {163return Center(164child: AnimatedBuilder(165animation: animation,166builder: (context, child) {167return SizedBox(168height: animation.value,169width: animation.value,170child: child,171);172},173child: child,174),175);176}177}178179class AnimatedBuilderDemo extends StatefulWidget {180const AnimatedBuilderDemo({super.key});181182@override183State<AnimatedBuilderDemo> createState() => _AnimatedBuilderDemoState();184}185186class _AnimatedBuilderDemoState extends State<AnimatedBuilderDemo>187with SingleTickerProviderStateMixin {188late AnimationController _controller;189late Animation<double> _animation;190191@override192void initState() {193super.initState();194_controller = AnimationController(195duration: const Duration(seconds: 2),196vsync: this,197);198199_animation = Tween<double>(begin: 0, end: 300).animate(_controller);200_controller.forward();201}202203@override204void dispose() {205_controller.dispose();206super.dispose();207}208209@override210Widget build(BuildContext context) {211return Scaffold(212appBar: AppBar(title: const Text('Animated Builder')),213body: GrowTransition(animation: _animation, child: const LogoWidget()),214);215}216}217218/// Multiple simultaneous animations with status monitoring219class MultiPropertyAnimation extends AnimatedWidget {220const MultiPropertyAnimation({221super.key,222required Animation<double> animation,223}) : super(listenable: animation);224225static final _opacityTween = Tween<double>(begin: 0.1, end: 1);226static final _sizeTween = Tween<double>(begin: 0, end: 300);227static final _colorTween = ColorTween(begin: Colors.red, end: Colors.blue);228229@override230Widget build(BuildContext context) {231final animation = listenable as Animation<double>;232return Center(233child: Opacity(234opacity: _opacityTween.evaluate(animation),235child: Container(236height: _sizeTween.evaluate(animation),237width: _sizeTween.evaluate(animation),238decoration: BoxDecoration(239color: _colorTween.evaluate(animation),240borderRadius: BorderRadius.circular(12),241),242child: const FlutterLogo(),243),244),245);246}247}248249class MultiPropertyDemo extends StatefulWidget {250const MultiPropertyDemo({super.key});251252@override253State<MultiPropertyDemo> createState() => _MultiPropertyDemoState();254}255256class _MultiPropertyDemoState extends State<MultiPropertyDemo>257with SingleTickerProviderStateMixin {258late AnimationController _controller;259late Animation<double> _animation;260261@override262void initState() {263super.initState();264_controller = AnimationController(265duration: const Duration(seconds: 2),266vsync: this,267);268269_animation = CurvedAnimation(parent: _controller, curve: Curves.easeIn)270..addStatusListener((status) {271if (status == AnimationStatus.completed) {272_controller.reverse();273} else if (status == AnimationStatus.dismissed) {274_controller.forward();275}276});277278_controller.forward();279}280281@override282void dispose() {283_controller.dispose();284super.dispose();285}286287@override288Widget build(BuildContext context) {289return Scaffold(290appBar: AppBar(title: const Text('Multi Property')),291body: MultiPropertyAnimation(animation: _animation),292);293}294}295296/// Main demo widget showing all examples297class LogoAnimationDemo extends StatelessWidget {298const LogoAnimationDemo({super.key});299300@override301Widget build(BuildContext context) {302return Scaffold(303appBar: AppBar(title: const Text('Explicit Animations')),304body: Center(305child: Column(306mainAxisAlignment: MainAxisAlignment.center,307children: [308ElevatedButton(309onPressed: () => Navigator.of(context).push(310MaterialPageRoute<void>(311builder: (context) => const BasicExplicitAnimation(),312),313),314child: const Text('Basic Explicit'),315),316ElevatedButton(317onPressed: () => Navigator.of(context).push(318MaterialPageRoute<void>(319builder: (context) => const AnimatedWidgetDemo(),320),321),322child: const Text('Animated Widget'),323),324ElevatedButton(325onPressed: () => Navigator.of(context).push(326MaterialPageRoute<void>(327builder: (context) => const AnimatedBuilderDemo(),328),329),330child: const Text('Animated Builder'),331),332ElevatedButton(333onPressed: () => Navigator.of(context).push(334MaterialPageRoute<void>(335builder: (context) => const MultiPropertyDemo(),336),337),338child: const Text('Multi Property'),339),340],341),342),343);344}345}346