flutter新项目中需要将多张连续图片动画播放出来,对Tween组件进行封装。
直接贴封装好的代码:
import 'package:flutter/material.dart';
class AnimationImageWidget extends StatefulWidget {
final List<String> _assetList;
final double? width;
final double? height;
bool autoPlay;
bool loop;
int interval;
AnimationImageWidget(this._assetList, {Key? key, this.width, this.height, this.interval = 60, this.autoPlay = true, this.loop = true}) : super(key: key);
@override
State<StatefulWidget> createState() {
return AnimationImageState();
}
}
class AnimationImageState extends State<AnimationImageWidget> with SingleTickerProviderStateMixin,AutomaticKeepAliveClientMixin<AnimationImageWidget> {
// 动画控制
late Animation<double> _animation;
late AnimationController _controller;
int interval = 200;
@override
void initState() {
super.initState();
if (widget.interval != null) {
interval = widget.interval;
}
final int imageLength = widget._assetList.length;
final int maxTime = interval * imageLength;
_controller = AnimationController(duration: Duration(milliseconds: maxTime), vsync: this);
_controller.addStatusListener((AnimationStatus status) {
if (status == AnimationStatus.completed && widget.loop) {
_controller.forward(from: 0.0);
}
});
_animation = Tween<double>(begin: 0, end: imageLength.toDouble()).animate(_controller)
..addListener(() {
setState(() {
});
});
if (widget.autoPlay) {
_controller.forward();
}
}
void startAnimation() => _controller.forward();
void stopAnimation() => _controller.stop();
void reStartAnimation(){
_controller.reset();
_controller.forward();
}
@override
void didUpdateWidget(AnimationImageWidget oldWidget) {
if (widget.autoPlay) {
_controller.forward();
}
super.didUpdateWidget(oldWidget);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
List<Widget> images = [];
@override
Widget build(BuildContext context) {
super.build(context);
return Container(alignment: AlignmentDirectional.center, child: Image.asset(
widget._assetList[_animation.value.floor() % widget._assetList.length],
width: widget.width,
height: widget.height,
fit: BoxFit.cover,
gaplessPlayback: true,///加载下一个动画前保留当前动画防止闪烁
));
}
@override
bool get wantKeepAlive => true;
}
使用方法:
AnimationImageWidget(ResDrawable.guide,key: _cotroller1,width: double.infinity,height: double.infinity,interval: 60,autoPlay: true,loop: true)
其中ResDrawable.guide为你图片路径地址的list;
_cotroller为动画控制器,可以进行动画播放、暂停,如:
GlobalKey<AnimationImageState> _cotroller = GlobalKey<AnimationImageState>();
_cotroller.currentState?.reStartAnimation();
_cotroller.currentState?.stopAnimation();
width、height为宽高;
interval为动画间隔;
autoPlay为是否自动播放;
loop为是否循环播放;
使用非常方便,但如果使用TabView和PageView,需要禁用自动播放,用过控制器来进行单独一页播放,否则会引起性能问题。