import 'package:flutter/material.dart'; import 'package:flutter_svga/flutter_svga.dart'; import 'package:yumi/ui_kit/components/sc_tts.dart'; import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart'; class SVGAHeadwearWidget extends StatefulWidget { // 资源路径(网络URL或本地assets路径) final String resource; // 尺寸 final double? width; final double? height; // 动画控制参数 final bool autoPlay; final int loops; // 循环次数(0表示无限循环) final bool clearsAfterStop; // 缓存控制 final bool useCache; // 回调函数 final VoidCallback? onCompleted; final Function(String)? onError; final VoidCallback? onStartLoading; final VoidCallback? onFinishLoading; const SVGAHeadwearWidget({ Key? key, required this.resource, this.width, this.height, this.autoPlay = true, this.loops = 0, this.clearsAfterStop = true, this.useCache = true, this.onCompleted, this.onError, this.onStartLoading, this.onFinishLoading, }) : super(key: key); @override _SVGAHeadwearWidgetState createState() => _SVGAHeadwearWidgetState(); } class _SVGAHeadwearWidgetState extends State with SingleTickerProviderStateMixin { SVGAAnimationController? _animationController; bool _isLoading = true; bool _isNetworkResource = false; bool _hasError = false; @override void initState() { super.initState(); _isNetworkResource = widget.resource.startsWith('http'); _animationController = SVGAAnimationController(vsync: this); if (widget.autoPlay) { _loadAnimation(); } // 添加动画状态监听 _animationController?.addStatusListener((status) { if (status == AnimationStatus.completed && widget.onCompleted != null) { widget.onCompleted!(); } }); } // 加载动画(带缓存) Future _loadAnimation() async { if (widget.onStartLoading != null) { widget.onStartLoading!(); } setState(() { _isLoading = true; _hasError = false; }); try { // 检查缓存 MovieEntity? videoItem; if (widget.useCache) { videoItem = SCGiftVapSvgaManager().videoItemCache[widget.resource]; } // 如果没有缓存,则进行解析 if (videoItem == null) { videoItem = _isNetworkResource ? await SVGAParser.shared.decodeFromURL(widget.resource) : await SVGAParser.shared.decodeFromAssets(widget.resource); videoItem.autorelease =false; // 存入缓存 if (widget.useCache) { SCGiftVapSvgaManager().videoItemCache[widget.resource] = videoItem; } } if (mounted) { setState(() { _animationController?.videoItem = videoItem; _isLoading = false; }); // 根据循环次数设置播放方式 if (widget.loops == 0) { _animationController?.repeat(); } else { _animationController?.repeat(count: widget.loops); } if (widget.onFinishLoading != null) { widget.onFinishLoading!(); } } } catch (e) { if (mounted) { setState(() { _isLoading = false; _hasError = true; }); } if (widget.onError != null) { SCTts.show("fail-${e.toString()}"); widget.onError!(e.toString()); } } } // 播放动画 void play() { if (_animationController?.videoItem != null) { _animationController?.reset(); if (widget.loops == 0) { _animationController?.repeat(); } else { _animationController?.repeat(count: widget.loops); } } else { _loadAnimation(); } } // 暂停动画 void pause() { _animationController?.stop(); } // 停止动画 void stop() { _animationController?.stop(); if (widget.clearsAfterStop) { _animationController?.videoItem = null; } } // 重新加载动画 void reload() { if (widget.useCache) { // 清除缓存项 SCGiftVapSvgaManager().videoItemCache.remove(widget.resource); } _loadAnimation(); } @override void dispose() { stop(); _animationController?.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (_isLoading && !widget.autoPlay) { return Container( width: widget.width, height: widget.height, child: Center(child: CircularProgressIndicator()), ); } if (_hasError) { return Container(); } return Container( width: widget.width, height: widget.height, child: _animationController != null && _animationController!.videoItem != null ? SVGAImage( _animationController!, fit: BoxFit.fill, clearsAfterStop: widget.clearsAfterStop, ) : Container(), ); } }