Files
ai_chat_assistant/lib/widgets/large_audio_wave.dart
Ding, Shuo 4035804b73 1、增加悬浮按钮的小声波效果[未使用]
2、增加底部按钮的大声波效果
3、更换footer底部图标
2025-08-12 16:47:34 +08:00

87 lines
2.9 KiB
Dart
Raw 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 AudioWaveLarge extends StatelessWidget {
/// 动画控制器,用于驱动波形动画
final AnimationController animationController;
/// 波形颜色,默认为白色
final Color waveColor;
/// 波形条间距默认为4.0px
final double barSpacing;
/// 总宽度默认为148.0px
final double totalWidth;
/// 最大高度默认为22.0px
final double maxHeight;
/// 最小高度默认为4.0px
final double minHeight;
/// 构造函数
const AudioWaveLarge({
super.key,
required this.animationController,
this.waveColor = Colors.white,
this.barSpacing = 4.0,
this.totalWidth = 148.0,
this.maxHeight = 22.0,
this.minHeight = 4.0,
});
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
key: const Key('audioWaveAnimation'), // 为音频波形添加key便于引用
animation: animationController,
builder: (context, child) {
// 根据总宽度动态计算竖线数量
// 每个竖线宽度2px + 间距,保持合理的密度
final barWidthWithSpacing = 2 + barSpacing;
final dynamicBarCount = (totalWidth / barWidthWithSpacing).floor();
final actualBarCount = dynamicBarCount > 0 ? dynamicBarCount : 1;
return SizedBox(
width: totalWidth, // 设置动态宽度
height: maxHeight, // 设置固定高度
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, // 垂直居中
children: List.generate(actualBarCount, (index) {
// 为每个竖线创建不同的相位,使动画不同步
final phase = index * 0.3;
// 设置不同的频率增加自然变化
final frequency = 1.0 + (index % 3) * 0.2;
// 计算波形高度
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(2), // 圆角效果
),
),
);
}),
),
);
},
);
}
}