flutter 的lottie执行一次动画后关闭

复制代码
flutter_gen  管理静态资源,包含lottile的管理

CBAnimationBuilder 自动管理controller

Dart 复制代码
import 'package:flutter/material.dart';

typedef CBAnimationWidgetBuilder = Widget Function(
  BuildContext context,
  Widget? child,
  Animation animation,
  AnimationController controller,
);

typedef CBAnimationEndCallback = void Function(
    Animation animation, AnimationController controller);

class CBAnimationBuilder extends StatefulWidget {
  final Duration duration;
  final bool repeat;
  final Widget? child;
  final CBAnimationWidgetBuilder builder;
  final CBAnimationEndCallback? onEnd;

  const CBAnimationBuilder({
    super.key,
    this.duration = const Duration(milliseconds: 300),
    this.repeat = false,
    this.child,
    required this.builder,
    this.onEnd,
  });

  @override
  State<StatefulWidget> createState() => _CBAnimationBuilderState();
}

class _CBAnimationBuilderState extends State<CBAnimationBuilder>
    with TickerProviderStateMixin {
  late final AnimationController controller;
  late final Animation<double> animation;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: widget.duration,
    );
    animation = Tween<double>(begin: 0, end: 1).animate(controller);
    controller.forward();
    if (widget.repeat) {
      controller.repeat();
    }
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: animation,
      child: widget.child,
      builder: (context, child) {
        if (animation.isCompleted || animation.isDismissed) {
          widget.onEnd?.call(animation, controller);
        }
        return widget.builder(context, child, animation, controller);
      },
    );
  }
}

使用

Dart 复制代码
import 'package:bcf/app/bc_widget/animation_builder.dart';
import 'package:bcf/app/bc_widget/bc_widgets.dart';
import 'package:bcf/gen/assets.gen.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';

enum LottieType {
  peach,
  eggplant,
  fire,
  rainbow,
  chili;

  Widget get lottie {
    return switch (this) {
      LottieType.peach => CBAnimationBuilder(
        repeat: false,
        duration: const Duration(seconds: 1),
        builder: (ctx, Widget? w, a, c) {
          return Assets.lottie.commentAnimatPeach.lottie(controller: c);
        },
        onEnd: (a, c) => Get.back(),
      ),
      LottieType.eggplant => CBAnimationBuilder(
        repeat: false,
        duration: const Duration(seconds: 1),
        builder: (ctx, Widget? w, a, c) {
          return Assets.lottie.commentAnimatEggplant.lottie(controller: c);
        },
        onEnd: (a, c) => Get.back(),
      ),
      LottieType.fire => CBAnimationBuilder(
        repeat: false,
        duration: const Duration(seconds: 1),
        builder: (ctx, Widget? w, a, c) {
          return Assets.lottie.commentAnimatFire.lottie(controller: c);
        },
        onEnd: (a, c) => Get.back(),
      ),
      LottieType.rainbow => CBAnimationBuilder(
        repeat: false,
        duration: const Duration(seconds: 1),
        builder: (ctx, Widget? w, a, c) {
          return Assets.lottie.commentAnimatRainbow.lottie(controller: c);
        },
        onEnd: (a, c) => Get.back(),
      ),
      LottieType.chili => CBAnimationBuilder(
        repeat: false,
        duration: const Duration(seconds: 1),
        builder: (ctx, Widget? w, a, c) {
          return Assets.lottie.commentAnimatChili.lottie(controller: c);
        },
        onEnd: (a, c) => Get.back(),
      ),
    };
  }
}

class CommentLottiePanel extends StatelessWidget {
  const CommentLottiePanel({super.key, this.onComplete});

  final Function(LottieType)? onComplete;

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.symmetric(horizontal: 22.w, vertical: 10.h),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          DefaultInWell(onTap: () => openShowLottie(LottieType.peach), child: Assets.images.icPeach.image(height: 49.h)),
          DefaultInWell(onTap: () => openShowLottie(LottieType.eggplant), child: Assets.images.icEggplant.image(height: 49.h)),
          DefaultInWell(onTap: () => openShowLottie(LottieType.fire), child: Assets.images.icFire.image(height: 49.h)),
          DefaultInWell(onTap: () => openShowLottie(LottieType.rainbow), child: Assets.images.icRainbow.image(height: 49.h)),
          DefaultInWell(onTap: () => openShowLottie(LottieType.chili), child: Assets.images.icChili.image(height: 49.h)),
        ],
      ),
    );
  }

  openShowLottie(LottieType type) async {
    await Get.dialog(
        barrierDismissible: false,
        SizedBox(height: 1.sh, width: 2.sw, child: type.lottie));
    onComplete?.call(type);
  }
}
相关推荐
Owen_Q9 分钟前
Denso Create Programming Contest 2025(AtCoder Beginner Contest 413)
开发语言·算法·职场和发展
·云扬·26 分钟前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
liulilittle1 小时前
C++ i386/AMD64平台汇编指令对齐长度获取实现
c语言·开发语言·汇编·c++
小蜜蜂嗡嗡1 小时前
flutter更改第三方库pub get的缓存目录;更改.gradle文件夹存放目录
flutter
Thomas_YXQ1 小时前
Unity URP法线贴图实现教程
开发语言·unity·性能优化·游戏引擎·unity3d·贴图·单一职责原则
Zz_waiting.2 小时前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象
Touper.2 小时前
JavaSE -- 泛型详细介绍
java·开发语言·算法
sun0077002 小时前
std::forward作用
开发语言·c++·算法
某非著名程序员3 小时前
Flutter 新手绕不过的坑:ListView 为啥顶部老有空白?
flutter·客户端