1.线性动画
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: AnimateApp(), ); } } class AnimateApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _AnimateAppState(); } } class _AnimateAppState extends State<AnimateApp> with SingleTickerProviderStateMixin { AnimationController controller; Animation<double> animation; @override void initState() { super.initState(); // 创建 AnimationController 对象 controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); // 通过 Tween 对象 创建 Animation 对象 animation = Tween(begin: 50.0, end: 200.0).animate(controller) ..addListener(() { // 注意:这句不能少,否则 widget 不会重绘,也就看不到动画效果 setState(() {}); }); // 执行动画 controller.forward(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'AnimateApp', theme: ThemeData( primaryColor: Colors.blue ), home: Scaffold( appBar: AppBar( title: Text('AnimateApp'), ), body: Center( child: Container( // 获取动画的值赋给 widget 的宽高 animation.value, height: animation.value, decoration: BoxDecoration( color: Colors.redAccent ), ), ) ) ); } @override void dispose() { // 资源释放 controller.dispose(); super.dispose(); } }
2.非线性动画,在1.的基础上修改部分代码
controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 2000)); // 非线性动画 final CurvedAnimation curve = CurvedAnimation( parent: controller, curve: Curves.elasticOut); animation = Tween(begin: 50.0, end: 200.0).animate(curve) ..addListener(() { setState(() {}); });
3.给 Animation
添加 addStatusListener(...)
来监听当前动画的状态,如:动画是否播放完成。我们可以给上面的例子加一个状态监听,让动画无限执行:
animation = Tween(begin: 50.0, end: 200.0).animate(curve) ..addListener(() { setState(() {}); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) { controller.reverse(); } else if (status == AnimationStatus.dismissed) { controller.forward(); } });
AnimationStatus.completed
表示动画在结束时停止的状态,这个时候我们让动画反向执行(从后往前);AnimationStatus.dismissed
表示动画在开始时就停止的状态,这个时候我们让动画正常执行(从前往后)。这样就可以让动画无限执行了。4.
Tween
还可以接受 Color
类型的参数,实现颜色渐变的效果,下面让 widget 的颜色从 红色 渐变到 蓝色Animation<Color> animation;
controller = AnimationController( duration: const Duration(milliseconds: 3000), vsync: this); animation = ColorTween(begin: Colors.redAccent, end: Colors.blue).animate( controller) ..addListener(() { setState(() {}); }); controller.forward(); ... child: Container( decoration: BoxDecoration( color: animation.value ), margin: EdgeInsets.symmetric(vertical: 10.0), height: 200.0, 200.0, ),
最后的例子
import 'package:flutter/material.dart'; void main() { runApp(SampleApp()); } class SampleApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Sample App', theme: ThemeData( primarySwatch: Colors.blue, ), home: AnimateApp(), ); } } class AnimateApp extends StatefulWidget { @override State<StatefulWidget> createState() { return _AnimateAppState(); } } class _AnimateAppState extends State<AnimateApp> with SingleTickerProviderStateMixin { AnimationController controller; // Animation<double> animation; Animation<Color> animation; @override void initState() { super.initState(); // 线性 // // 创建 AnimationController 对象 // controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000)); // // 通过 Tween 对象 创建 Animation 对象 // animation = Tween(begin: 50.0, end: 200.0).animate(controller) // ..addListener(() { // // 注意:这句不能少,否则 widget 不会重绘,也就看不到动画效果 // setState(() {}); // }); //// 非线性 // controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000)); //// 非线性动画 // final CurvedAnimation curve = CurvedAnimation(parent: controller, curve: Curves.elasticOut); // animation = Tween(begin: 50.0, end: 200.0).animate(curve) // ..addListener(() { // setState(() {}); // }); // 通过给 Animation 添加 addStatusListener(...) 来监听当前动画的状态 // // 非线性 // controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000)); // // 非线性动画 // final CurvedAnimation curve = CurvedAnimation(parent: controller, curve: Curves.elasticOut); // animation = Tween(begin: 50.0, end: 200.0).animate(curve) // ..addListener(() { // setState(() {}); // }) // ..addStatusListener((status) { // if (status == AnimationStatus.completed) {//表示动画在结束时停止的状态 // controller.reverse();//动画反向执行(从后往前) // } else if (status == AnimationStatus.dismissed) {//表示动画在开始时就停止的状态 // controller.forward();//动画正常执行(从前往后) // } // }); // Tween 还可以接受 Color 类型的参数,实现颜色渐变的效果,下面让 widget 的颜色从 红色 渐变到 蓝色 controller = AnimationController(duration: const Duration(milliseconds: 3000), vsync: this); animation = ColorTween(begin: Colors.redAccent, end: Colors.blue).animate(controller) ..addListener(() { setState(() {}); }) ..addStatusListener((status) { if (status == AnimationStatus.completed) {//表示动画在结束时停止的状态 controller.reverse();//动画反向执行(从后往前) } else if (status == AnimationStatus.dismissed) {//表示动画在开始时就停止的状态 controller.forward();//动画正常执行(从前往后) } }); // 执行动画 controller.forward(); } @override Widget build(BuildContext context) { return MaterialApp( title: 'AnimateApp', theme: ThemeData( primaryColor: Colors.blue ), home: Scaffold( appBar: AppBar( title: Text('AnimateApp'), ), body: Center( child: Container( decoration: BoxDecoration( color: animation.value ), margin: EdgeInsets.symmetric(vertical: 10.0), height: 200.0, 200.0, ), // child: Container( // // 获取动画的值赋给 widget 的宽高 // animation.value, // height: animation.value, // decoration: BoxDecoration( // color: Colors.redAccent // ), // ), ) ) ); } @override void dispose() { // 资源释放 controller.dispose(); super.dispose(); } }