cheer_reward_widget.dart 2.87 KB
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';

import '../../utils/log_util.dart';

class CheerRewardWidget extends StatefulWidget {
  final String lottieFile;
  final double width;
  final double height;
  final bool isPlaying;
  final VoidCallback onAnimationEnd;

  const CheerRewardWidget({
    Key? key,
    required this.lottieFile,
    required this.width,
    required this.height,
    required this.isPlaying,
    required this.onAnimationEnd,
  }) : super(key: key);

  @override
  _CheerRewardWidgetState createState() => _CheerRewardWidgetState();
}

class _CheerRewardWidgetState extends State<CheerRewardWidget>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final Future<LottieComposition> _futureComposition;
  bool _isVisible = false;
  static const String TAG = "CheerRewardWidget";

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
    _loadComposition();
  }

  @override
  void didUpdateWidget(CheerRewardWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.isPlaying && !_controller.isAnimating) {
      _startAnimation();
    }
  }

  void _loadComposition() {
    _futureComposition = _loadLottieComposition();

    if (widget.isPlaying) {
      _startAnimation();
    }
  }

  Future<LottieComposition> _loadLottieComposition() async {
    return AssetLottie(widget.lottieFile).load();
  }

  void _startAnimation() {
    Log.d("$TAG ${identityHashCode(this)} _startAnimation");
    setState(() {
      _isVisible = true;
    });

    _futureComposition.then((composition) {
      Log.d("$TAG ${identityHashCode(this)} _futureComposition.then duration=${composition.duration}");
      _controller.duration = composition.duration;
      _controller.forward().whenCompleteOrCancel(() {
        if (mounted) {
          setState(() {
            _isVisible = false;
          });
        }
        widget.onAnimationEnd(); // 调用外部回调函数
      });
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
          width: widget.width,
          height: widget.height,
          child: FutureBuilder<LottieComposition>(
              future: _futureComposition,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  final composition = snapshot.data!;
                  return Lottie(
                    composition: composition,
                    controller: _controller,
                    renderCache: RenderCache.raster,
                    width: widget.width,
                    height: widget.height,
                  );
                } else {
                  return const SizedBox.shrink();
                }
              })),
    );
  }
}