Skip to content

Commit 47928b2

Browse files
committed
Add properties onAnimationBegin, onAnimationEnd, iterationCount, direction, delay, iterationDelay, and iterationInfinite
1 parent d886a27 commit 47928b2

File tree

1 file changed

+142
-31
lines changed

1 file changed

+142
-31
lines changed

lib/animated_config.dart

Lines changed: 142 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,69 +32,172 @@ enum AnimatedType { opacity, scale, translateX, translateY, skewX, skewY, rotate
3232

3333
const Duration _kDefaultDuration = const Duration(seconds: 1);
3434

35+
enum AnimatedDirection { normal, reverse, alternate, alternateReverse }
36+
3537
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);
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+
6081
class 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

Comments
 (0)