import 'package:flutter/material.dart'; import 'dart:math' as math; /// 小型按钮波形动画组件 /// /// 用于显示适合小按钮的波形动画,竖线数量根据容器宽度自动计算 class AudioWaveLargeMini extends StatelessWidget { /// 动画控制器,用于驱动波形动画 final AnimationController animationController; /// 波形颜色,默认为白色 final Color waveColor; /// 波形条间距,默认为3.0px final double barSpacing; /// 最小高度比例,默认为0.3(相对于容器高度) final double minHeightRatio; /// 最大高度比例,默认为1.0(相对于容器高度) final double maxHeightRatio; /// 构造函数 const AudioWaveLargeMini({ super.key, required this.animationController, this.waveColor = Colors.white, this.barSpacing = 3.0, this.minHeightRatio = 0.3, this.maxHeightRatio = 1.0, }); @override Widget build(BuildContext context) { return AnimatedBuilder( animation: animationController, // 使用传入的动画控制器 builder: (context, child) { return LayoutBuilder( builder: (context, constraints) { // 根据容器宽度动态计算竖线数量 final containerWidth = constraints.maxWidth; final containerHeight = constraints.maxHeight; final barWidthWithSpacing = 2 + barSpacing; final barCount = (containerWidth / barWidthWithSpacing).floor().clamp(3, 15); return Row( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, // 改为垂直居中,和AudioWaveLarge一致 children: List.generate(barCount, (index) { // 为每个竖线设置不同的相位,和AudioWaveLarge保持一致 final phase = index * 0.3; // 改为0.3,和AudioWaveLarge一致 // 设置不同的频率变化 final frequency = 1.0 + (index % 3) * 0.2; // 根据容器高度计算波形高度,使用和AudioWaveLarge相同的算法 final minHeight = containerHeight * minHeightRatio; final maxHeight = containerHeight * maxHeightRatio; final height = minHeight + (maxHeight - minHeight) * math.sin( (animationController.value * 2 * math.pi * frequency) + phase ).abs(); // 构建单个波形条 return Padding( padding: EdgeInsets.symmetric(horizontal: barSpacing / 2), child: Container( width: 2, // 波形条宽度2px height: height, // 高度随动画变化 decoration: BoxDecoration( color: waveColor, borderRadius: BorderRadius.circular(1), // 圆角效果 ), ), ); }), ); }, ); }, ); } }