import 'package:flutter/material.dart'; import 'package:lottie/lottie.dart'; import 'package:wow_english/common/widgets/throttledGesture_gesture_detector.dart'; import '../../utils/log_util.dart'; /// 录音组件 class _RecorderPlaybackWidget extends StatefulWidget { final bool isClickable; final bool isPlaying; final VoidCallback? onTap; final double width; final double height; const _RecorderPlaybackWidget({ Key? key, required this.isClickable, required this.isPlaying, required this.onTap, required this.width, required this.height, }) : super(key: key); @override _RecorderPlaybackWidgetState createState() => _RecorderPlaybackWidgetState(); } class _RecorderPlaybackWidgetState extends State<_RecorderPlaybackWidget> with SingleTickerProviderStateMixin { late final AnimationController _controller; late final LottieComposition _composition; static const String TAG = "RecorderPlaybackWidget"; bool _isPlaying = false; @override void initState() { super.initState(); _controller = AnimationController(vsync: this); _loadComposition(); _controller.addListener(() { // Log.d("$TAG addListener _controller=${_controller.status}"); }); } Future _loadComposition() async { final composition = await AssetLottie('assets/lotties/recorder_back.zip').load(); setState(() { _composition = composition; _controller.duration = _composition.duration; }); if (widget.isPlaying) { _playAnimation(); } } void _playAnimation() { _controller.reset(); _controller.repeat( min: 2 / _composition.endFrame, max: 22 / _composition.endFrame, ); } void _stopAnimation() { _controller.stop(); _resetAnimation(); } void _resetAnimation() { setState(() { _isPlaying = false; _controller.value = 1; // _controller.repeat( // min: 1 / _composition.endFrame, // max: 1 / _composition.endFrame, // ); }); } void _displayAnimation(bool clickable) { if (clickable) { _controller.value = 1; // _controller.repeat( // min: 1, // max: 1, // ); } else { _controller.value = 0; // _controller.repeat( // min: 0, // max: 0, // ); } } @override void didUpdateWidget(_RecorderPlaybackWidget oldWidget) { super.didUpdateWidget(oldWidget); Log.d( "$TAG didUpdateWidget widget=${widget.isPlaying} oldWidget=${oldWidget.isPlaying} _isPlaying=$_isPlaying"); if (widget.isPlaying && !_isPlaying) { setState(() { _isPlaying = true; }); _playAnimation(); } else if (!widget.isPlaying && _isPlaying) { _stopAnimation(); } if (!_isPlaying) { _displayAnimation(widget.isClickable); } } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return ThrottledGestureDetector( onTap: widget.isClickable ? widget.onTap : null, child: Opacity( opacity: widget.isClickable ? 1.0 : 0.5, // 设置透明度 child: Lottie( composition: _composition, controller: _controller, renderCache: RenderCache.raster, width: widget.width, height: widget.height, ), ), ); } }