@@ -32,69 +32,172 @@ enum AnimatedType { opacity, scale, translateX, translateY, skewX, skewY, rotate
3232
3333const Duration _kDefaultDuration = const Duration (seconds: 1 );
3434
35+ enum AnimatedDirection { normal, reverse, alternate, alternateReverse }
36+
3537class SmartAnimatedWidget extends StatefulWidget {
36- SmartAnimatedWidget ({
37- Key key,
38- this .from,
39- this .to,
40- this .configMap,
41- this .child,
42- this .curve,
43- this .duration = _kDefaultDuration,
44- this .autoPlay = false ,
45- this .onTransitionEnd,
46- }) : super (key: key);
38+ SmartAnimatedWidget (
39+ {Key key,
40+ this .from,
41+ this .to,
42+ this .configMap,
43+ this .child,
44+ this .curve,
45+ this .duration = _kDefaultDuration,
46+ this .autoPlay = false ,
47+ this .onAnimationEnd,
48+ this .onAnimationBegin,
49+ this .iterationCount = 1 ,
50+ this .iterationInfinite = false ,
51+ this .direction = AnimatedDirection .normal,
52+ this .delay = const Duration (seconds: 0 ),
53+ this .iterationDelay = const Duration (seconds: 0 )})
54+ : super (key: key);
4755 final AnimatedConfig from;
4856 final AnimatedConfig to;
4957 final Map <double , AnimatedConfig > configMap;
5058 final Widget child;
5159 final Curve curve;
5260 final Duration duration;
5361 final bool autoPlay;
54- final VoidCallback onTransitionEnd;
62+ final VoidCallback onAnimationEnd;
63+ final VoidCallback onAnimationBegin;
64+ final int iterationCount;
65+ final AnimatedDirection direction;
66+ final Duration delay;
67+ final Duration iterationDelay;
68+ final bool iterationInfinite;
5569
5670 @override
5771 SmartAnimatedWidgetState createState () => SmartAnimatedWidgetState ();
5872}
5973
74+ enum _ad {
75+ forward,
76+ reverse,
77+ }
78+
79+ typedef ValueCallBack <T > = T Function (T t);
80+
6081class SmartAnimatedWidgetState extends State <SmartAnimatedWidget > with SingleTickerProviderStateMixin <SmartAnimatedWidget > {
6182 AnimationController _controller;
6283 Animation <double > _animation;
6384 bool _animating = false ; //是否正在动画
85+ int _iteration = 0 ;
86+ Map <double ,AnimatedConfig > _configMap ;
87+
6488
6589 @override
6690 void initState () {
67- // TODO: implement initState
6891 super .initState ();
92+ _configMap = widget.configMap;
6993 _controller = AnimationController (vsync: this , duration: widget.duration);
70- _animation = Tween <double >(begin: 0 , end: 1 ).animate (_controller);
94+ _animation = Tween <double >(begin: _begin () , end: 1 - _begin () ).animate (_controller);
7195 if (widget.autoPlay == true ) {
72- _controller.forward ();
73- _animating = true ;
96+ animate ();
7497 }
75- _controller.addStatusListener ((status) {
76- if (status == AnimationStatus .completed) {
77- if (widget.onTransitionEnd != null ) widget.onTransitionEnd ();
78- _animating = false ;
79- }
80- });
98+ // _controller.addStatusListener(_addStatusListener);
8199 }
82100
83- reset () {
84- _controller? .reset ();
101+
102+ @override
103+ void didUpdateWidget (SmartAnimatedWidget oldWidget) {
104+ super .didUpdateWidget (oldWidget);
105+ _configMap = widget.configMap;
106+ }
107+
108+ get animating => _animating;
109+
110+ ///
111+ /// 完成动画
112+ ///
113+ _finishAnimation () {
114+ if (widget.onAnimationEnd != null ) widget.onAnimationEnd ();
115+ _animating = false ;
116+ _iteration = 0 ;
117+ }
118+
119+ ///
120+ /// 是否可以动画
121+ ///
122+ bool _canAnimated () => widget.iterationInfinite == true || _iteration < widget.iterationCount;
123+
124+ ///
125+ /// 获取Tween的开始值
126+ ///
127+ double _begin () {
128+ switch (widget.direction) {
129+ case AnimatedDirection .reverse:
130+ case AnimatedDirection .alternateReverse:
131+ return 1 ;
132+ case AnimatedDirection .alternate:
133+ default :
134+ return 0 ;
135+ }
85136 }
86137
87- animate () {
88- if (_animating == false ) {
89- _controller.reset ();
90- _controller.forward ();
138+ void animate () {
139+ if (_animating == true ) return ;
140+ Future .delayed (widget.delay, () {
141+ if (widget.onAnimationBegin!= null )widget.onAnimationBegin ();
142+ _controller? .removeStatusListener (_addStatusListener);
143+ _controller? .reset ();
144+ _controller? .addStatusListener (_addStatusListener);
145+ _controller? .forward ();
146+ _iteration ++ ;
91147 _animating = true ;
148+ });
149+ }
150+
151+ ///
152+ /// 开始动画,内部使用
153+ ///
154+ void _animate (_ad ad, double from) {
155+ if (_canAnimated () == true ) {
156+ Future .delayed (widget.iterationDelay, () {
157+ if (ad == _ad.forward) {
158+ _controller? .forward (from: from);
159+ } else {
160+ _controller? .reverse (from: from);
161+ }
162+ _iteration++ ;
163+ });
164+ } else {
165+ _finishAnimation ();
166+ }
167+ }
168+
169+ ///添加动画状态监听
170+ void _addStatusListener (AnimationStatus status) {
171+ switch (widget.direction) {
172+ case AnimatedDirection .alternate:
173+ case AnimatedDirection .alternateReverse:
174+ if (status == AnimationStatus .completed) {
175+ if (_iteration % 2 == 1 ) _animate (_ad.reverse, 1 );
176+ if (_canAnimated () == false ) _finishAnimation ();
177+ } else if (status == AnimationStatus .dismissed) {
178+ if (_iteration % 2 == 0 ) _animate (_ad.forward, 0 );
179+ if (_canAnimated () == false ) _finishAnimation ();
180+ }
181+ break ;
182+ case AnimatedDirection .reverse:
183+ default :
184+ if (status == AnimationStatus .completed) {
185+ _animate (_ad.forward, 0 );
186+ } else if (status == AnimationStatus .dismissed) {
187+ if (_canAnimated () == false ) _finishAnimation ();
188+ }
92189 }
93190 }
94191
192+ reset () {
193+ _controller? .removeStatusListener (_addStatusListener);
194+ _controller? .reset ();
195+ }
196+
95197 @override
96198 void dispose () {
97199 // TODO: implement dispose
200+ _controller? .removeStatusListener (_addStatusListener);
98201 _controller? .dispose ();
99202 super .dispose ();
100203 }
@@ -132,7 +235,7 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
132235 rotateYTween = InterpolationTween (inputRange: inputRange, outputRange: [fc.rotateY ?? fc.rotate ?? 0 , tc.rotateY ?? tc.rotate ?? 0 ], curve: widget.curve);
133236 opacityTween = InterpolationTween (inputRange: inputRange, outputRange: [fc.opacity ?? 1 , tc.opacity ?? 1 ], curve: widget.curve);
134237 }
135- if (widget.configMap != null ) {
238+ if (_configMap != null ) {
136239 List <double > scaleXOutRange = [], scaleXInputRange = [];
137240 List <double > scaleYOutRange = [], scaleYInputRange = [];
138241 List <double > translateXOutRange = [], translateXInputRange = [];
@@ -142,8 +245,8 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
142245 List <double > rotateXOutRange = [], rotateXInputRange = [];
143246 List <double > rotateYOutRange = [], rotateYInputRange = [];
144247 List <double > opacityOutRange = [], opacityInputRange = [];
145- List <double > keysList = widget.configMap .keys.toList ();
146- Map <double , AnimatedConfig > configs = widget.configMap ;
248+ List <double > keysList = _configMap .keys.toList ();
249+ Map <double , AnimatedConfig > configs = _configMap ;
147250 keysList.sort (); //从小到大排序
148251 for (int i = 0 ; i < keysList.length; i++ ) {
149252 double key = keysList.elementAt (i);
@@ -257,4 +360,12 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
257360 ),
258361 );
259362 }
363+
364+ @override
365+ void didChangeDependencies () {
366+ super .didChangeDependencies ();
367+ _configMap = widget.configMap;
368+ }
369+
370+
260371}
0 commit comments