import 'package:flutter/material.dart'; class PlayBtnAnimation extends StatefulWidget { final Widget child; final bool isAnimating; final bool alwaysAnimate; final Duration duration; final Function()? onEnd; const PlayBtnAnimation( {Key? key, required this.child, required this.isAnimating, this.duration = const Duration(milliseconds: 150), this.onEnd, this.alwaysAnimate = false}) : super(key: key); @override State createState() => _PlayBtnAnimationState(); } class _PlayBtnAnimationState extends State with SingleTickerProviderStateMixin { late AnimationController controller; late Animation scale; @override void initState() { super.initState(); final halfDuration = widget.duration.inMilliseconds ~/ 2; controller = AnimationController( vsync: this, duration: Duration(milliseconds: halfDuration)); scale = Tween(begin: 1, end: 1.2).animate(controller); } @override void dispose() { controller.dispose(); super.dispose(); } @override void didUpdateWidget(covariant PlayBtnAnimation oldWidget) { super.didUpdateWidget(oldWidget); if (widget.isAnimating != oldWidget.isAnimating) { doAnimation(); } } Future doAnimation() async { if (widget.isAnimating) { await controller.forward(); await controller.reverse(); await Future.delayed(const Duration(milliseconds: 400)); widget.onEnd?.call(); } } @override Widget build(BuildContext context) { return ScaleTransition(scale: scale, child: widget.child); } }