You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

104 lines
3.1 KiB

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<SvgaPlayerWidget> createState() => _SvgaPlayerWidgetState();
}
class _SvgaPlayerWidgetState extends State<SvgaPlayerWidget>
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<void> _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!),
),
);
});
}
}