import 'package:flutter/material.dart'; import 'package:flutter_svga/flutter_svga.dart'; import 'package:get/get.dart'; import 'package:dating_touchme_app/controller/discover/svga_player_manager.dart'; /// SVGA 动画播放 Widget /// 监听 SvgaPlayerManager 的队列,自动播放 SVGA 动画 class SvgaPlayerWidget extends StatefulWidget { const SvgaPlayerWidget({super.key}); @override State createState() => _SvgaPlayerWidgetState(); } class _SvgaPlayerWidgetState extends State with SingleTickerProviderStateMixin { final SvgaPlayerManager _manager = SvgaPlayerManager.instance; SVGAAnimationController? _controller; SvgaAnimationItem? _currentItem; @override void initState() { super.initState(); // 监听队列变化 ever(_manager.currentItem, (item) { if (item != null && item != _currentItem) { _playAnimation(item); } }); } @override void dispose() { _controller?.dispose(); super.dispose(); } /// 播放动画 Future _playAnimation(SvgaAnimationItem item) async { // 如果正在播放,先停止 if (_controller != null) { _controller!.dispose(); _controller = null; } _currentItem = item; _controller = SVGAAnimationController(vsync: this); try { // 判断是网络 URL 还是本地资源 if (item.svgaFile.startsWith('http://') || item.svgaFile.startsWith('https://')) { // 网络 URL SVGAParser.shared.decodeFromURL(item.svgaFile).then((video) { if (mounted && _currentItem == item) { _controller!.videoItem = video; _controller!.repeat(); print('✅ SVGA 动画加载成功(网络): ${item.svgaFile}'); } }).catchError((error) { print('❌ SVGA 动画加载失败(网络): $error'); _manager.onAnimationError(error.toString()); }); } else { // 本地资源(assets) SVGAParser.shared.decodeFromAssets(item.svgaFile).then((video) { if (mounted && _currentItem == item) { _controller!.videoItem = video; _controller!.repeat(); print('✅ SVGA 动画加载成功(本地): ${item.svgaFile}'); } }).catchError((error) { print('❌ SVGA 动画加载失败(本地): $error'); _manager.onAnimationError(error.toString()); }); } // 监听动画完成(repeat 模式不会自动完成,需要手动停止) // 这里可以根据需要调整播放逻辑 } catch (e) { print('❌ SVGA 播放异常: $e'); _manager.onAnimationError(e.toString()); } } @override Widget build(BuildContext context) { return Obx(() { final currentItem = _manager.currentItem.value; final isPlaying = _manager.isPlaying.value; if (!isPlaying || currentItem == null || _controller == null) { return const SizedBox.shrink(); } return Positioned.fill( child: IgnorePointer( child: SVGAImage(_controller!), ), ); }); } }