Flutter AnimatedBuilder
创建动画的widget
Key key,
@required Listenable animation,
@required this.builder,
this.child,
animation:Animationcontroller //动画
child 动画作用的view
builder:每次controller值改变都会回到builder 重新生成view
import 'package:flutter/material.dart'; main()=>runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/buildAnimation', routes: { '/':(context)=>AnimationDemo(), '/test':(context)=>TestAnimation(), '/buildAnimation':(context)=>BuildAnimation(), }, ); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class BuildAnimation extends StatefulWidget{ @override State<StatefulWidget> createState() { // TODO: implement createState return BuildAnimationState(); } } class BuildAnimationState extends State<BuildAnimation> with TickerProviderStateMixin{ AnimationController animationController; var animation; @override void initState() { super.initState(); animationController = AnimationController( duration: Duration(seconds: 2), vsync: this); animation = Tween(begin: 20, end: 200).animate(animationController); animationController.forward(); //放到某个其他地方去启动, 会唤起Builder } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('builder'),), body: Container( double.infinity, height: double.infinity, child: Stack( children: <Widget>[ AnimatedBuilder( animation: animation, builder: (context, Widget child){ //child 可以定义要动的东西....这里先暂时省略了. return Positioned( left: animation.value/1.0, top: animation.value/1.0, child: Container(child: RaisedButton( child: Text('abc'),onPressed: (){ print(animation.value); }),), ); }, ), ], ), ), ); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class TestAnimation extends StatefulWidget{ @override State<StatefulWidget> createState() { return TestAnimationState(); } } class TestAnimationState extends State<TestAnimation> with TickerProviderStateMixin{ AnimationController animationController; Tween positionTween = Tween(begin: 20, end: 200); var animation; @override void initState() { super.initState(); animationController = AnimationController( vsync: this, duration: Duration(seconds: 1), ); animation = positionTween.animate(animationController); animationController.addListener((){ print(animationController.value); }); animationController.addStatusListener((value){ print('status: $value'); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('test'),), body: Container( double.infinity, height: double.infinity, color: Colors.black12, child: TestAnimationDemo(animationController: animationController,animation:animation), ), ); } } class TestAnimationDemo extends AnimatedWidget { AnimationController animationController; Animation animation; TestAnimationDemo({this.animationController, this.animation}):super(listenable:animationController); @override Widget build(BuildContext context) { return Stack( children: <Widget>[ Positioned( left: animation.value/1.0, top: animation.value/1.0, child: Container( child: IconButton(icon: Icon(Icons.forward), onPressed: (){ animationController.forward(); }), ), ), ], ); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// class AnimationDemo extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('AnimationDemo'), elevation: 0.0, ), body: AnimationDemoHome()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////// class AnimationDemoHome extends StatefulWidget { @override _AnimationDemoHomeState createState() => _AnimationDemoHomeState(); } class _AnimationDemoHomeState extends State<AnimationDemoHome> with TickerProviderStateMixin { AnimationController animationDemoController; Animation animation; Animation animationColor; CurvedAnimation curve; @override void initState() { super.initState(); animationDemoController = AnimationController( // value: 32.0, // lowerBound: 32.0, // upperBound: 100.0, duration: Duration(milliseconds: 1000), vsync: this, ); curve = CurvedAnimation( parent: animationDemoController, curve: Curves.bounceOut); animation = Tween(begin: 32.0, end: 100.0).animate(curve); animationColor = ColorTween(begin: Colors.red, end: Colors.red[900]).animate(curve); // animationDemoController.addListener(() { // // print('${animationDemoController.value}'); // setState(() {}); // }); animationDemoController.addStatusListener((AnimationStatus status) { print(status); }); // animationDemoController.forward(); } @override void dispose() { super.dispose(); animationDemoController.dispose(); } @override Widget build(BuildContext context) { return Center( child: AnimatedHeart( animations: [ animation, animationColor, ], controller: animationDemoController, ), ); } } class AnimatedHeart extends AnimatedWidget { final List animations; final AnimationController controller; AnimatedHeart({ this.animations, this.controller, }) : super(listenable: controller); @override Widget build(BuildContext context) { return IconButton( icon: Icon(Icons.favorite), iconSize: animations[0].value, color: animations[1].value, onPressed: () { switch (controller.status) { case AnimationStatus.completed: controller.reverse(); break; default: controller.forward(); } }, ); } }