Files
ai_chat_assistant/lib/widgets/mini_audio_wave.dart

83 lines
3.1 KiB
Dart
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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), // 圆角效果
),
),
);
}),
);
},
);
},
);
}
}