@@ -32,69 +32,172 @@ enum AnimatedType { opacity, scale, translateX, translateY, skewX, skewY, rotate
32
32
33
33
const Duration _kDefaultDuration = const Duration (seconds: 1 );
34
34
35
+ enum AnimatedDirection { normal, reverse, alternate, alternateReverse }
36
+
35
37
class 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);
47
55
final AnimatedConfig from;
48
56
final AnimatedConfig to;
49
57
final Map <double , AnimatedConfig > configMap;
50
58
final Widget child;
51
59
final Curve curve;
52
60
final Duration duration;
53
61
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;
55
69
56
70
@override
57
71
SmartAnimatedWidgetState createState () => SmartAnimatedWidgetState ();
58
72
}
59
73
74
+ enum _ad {
75
+ forward,
76
+ reverse,
77
+ }
78
+
79
+ typedef ValueCallBack <T > = T Function (T t);
80
+
60
81
class SmartAnimatedWidgetState extends State <SmartAnimatedWidget > with SingleTickerProviderStateMixin <SmartAnimatedWidget > {
61
82
AnimationController _controller;
62
83
Animation <double > _animation;
63
84
bool _animating = false ; //是否正在动画
85
+ int _iteration = 0 ;
86
+ Map <double ,AnimatedConfig > _configMap ;
87
+
64
88
65
89
@override
66
90
void initState () {
67
- // TODO: implement initState
68
91
super .initState ();
92
+ _configMap = widget.configMap;
69
93
_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);
71
95
if (widget.autoPlay == true ) {
72
- _controller.forward ();
73
- _animating = true ;
96
+ animate ();
74
97
}
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);
81
99
}
82
100
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
+ }
85
136
}
86
137
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 ++ ;
91
147
_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
+ }
92
189
}
93
190
}
94
191
192
+ reset () {
193
+ _controller? .removeStatusListener (_addStatusListener);
194
+ _controller? .reset ();
195
+ }
196
+
95
197
@override
96
198
void dispose () {
97
199
// TODO: implement dispose
200
+ _controller? .removeStatusListener (_addStatusListener);
98
201
_controller? .dispose ();
99
202
super .dispose ();
100
203
}
@@ -132,7 +235,7 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
132
235
rotateYTween = InterpolationTween (inputRange: inputRange, outputRange: [fc.rotateY ?? fc.rotate ?? 0 , tc.rotateY ?? tc.rotate ?? 0 ], curve: widget.curve);
133
236
opacityTween = InterpolationTween (inputRange: inputRange, outputRange: [fc.opacity ?? 1 , tc.opacity ?? 1 ], curve: widget.curve);
134
237
}
135
- if (widget.configMap != null ) {
238
+ if (_configMap != null ) {
136
239
List <double > scaleXOutRange = [], scaleXInputRange = [];
137
240
List <double > scaleYOutRange = [], scaleYInputRange = [];
138
241
List <double > translateXOutRange = [], translateXInputRange = [];
@@ -142,8 +245,8 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
142
245
List <double > rotateXOutRange = [], rotateXInputRange = [];
143
246
List <double > rotateYOutRange = [], rotateYInputRange = [];
144
247
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 ;
147
250
keysList.sort (); //从小到大排序
148
251
for (int i = 0 ; i < keysList.length; i++ ) {
149
252
double key = keysList.elementAt (i);
@@ -257,4 +360,12 @@ class SmartAnimatedWidgetState extends State<SmartAnimatedWidget> with SingleTic
257
360
),
258
361
);
259
362
}
363
+
364
+ @override
365
+ void didChangeDependencies () {
366
+ super .didChangeDependencies ();
367
+ _configMap = widget.configMap;
368
+ }
369
+
370
+
260
371
}
0 commit comments