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);
}
}