star_reward_widget.dart 2.79 KB
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';

class StarRewardAnimation extends StatefulWidget {
  final double width;
  final double height;
  final bool isPlaying;
  final int starCount;
  final VoidCallback onAnimationEnd;

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

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

class _StarRewardAnimationState extends State<StarRewardAnimation>
    with SingleTickerProviderStateMixin {
  late final AnimationController _controller;
  late final LottieComposition _composition;
  bool _isVisible = false;

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

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

  Future<void> _loadComposition() async {
    // final composition = await AssetLottie('assets/lotties/recorder_input.zip').load();
    // setState(() {
    //   _composition = composition;
    //   _controller.duration = _composition.duration;
    // });

    final composition = await _loadLottieComposition();
    setState(() {
      _composition = composition;
      _controller.duration = _composition.duration;
    });

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

  void _startAnimation() async {
    setState(() {
      _isVisible = true;
    });

    _controller.forward().whenComplete(() {
      setState(() {
        _isVisible = false;
      });
      widget.onAnimationEnd(); // 调用外部回调函数
    });
  }

  Future<LottieComposition> _loadLottieComposition() async {
    String assetPath;
    switch (widget.starCount) {
      case 1:
        assetPath = 'assets/lotties/star1_reward.zip';
        break;
      case 2:
        assetPath = 'assets/lotties/star2_reward.zip';
        break;
      case 3:
        assetPath = 'assets/lotties/star3_reward.zip';
        break;
      default:
        assetPath = 'assets/lotties/star3_reward.zip';
        break;
    }
    return await AssetLottie(assetPath).load();
  }

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

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        width: widget.width,
        height: widget.height,
        child: Lottie(
          composition: _composition,
          controller: _controller,
          renderCache: RenderCache.raster,
          width: widget.width,
          height: widget.height,
        ),
      ),
    );
  }
}