Flutter中使用Custom Painter创建动态波形图的问题排查
实现动态语音波形图(随振幅调整样式与颜色)
原代码仅绘制单条折线,无法实现目标中的上下对称柱状波形,且颜色未随振幅动态变化。以下是修改后的完整实现:
import 'package:flutter/material.dart'; class Waveform extends StatelessWidget { final List<double> amplitudes; const Waveform(this.amplitudes, {super.key}); @override Widget build(BuildContext context) { return SizedBox( height: 100.0, child: CustomPaint( painter: WaveformPainter(amplitudes), ), ); } } class WaveformPainter extends CustomPainter { final List<double> amplitudes; final double lineWidth = 4.0; WaveformPainter(this.amplitudes); @override void paint(Canvas canvas, Size size) { final double midY = size.height / 2; final double totalPoints = amplitudes.length; final double pointSpacing = size.width / totalPoints; // 定义振幅对应的颜色渐变区间 final colorGradient = LinearGradient( colors: [Colors.blue.withOpacity(0.3), Colors.blue, Colors.red], stops: const [0.0, 0.5, 1.0], ); for (int i = 0; i < amplitudes.length; i++) { final double amplitude = amplitudes[i].clamp(0.0, 1.0); // 确保振幅在0-1区间 final double x = i * pointSpacing + pointSpacing / 2; // 竖线居中 final double lineHeight = amplitude * midY; // 根据振幅获取对应颜色 final color = colorGradient.transform(amplitude); final paint = Paint() ..color = color ..strokeCap = StrokeCap.round ..strokeWidth = lineWidth; // 绘制上下对称的竖线 canvas.drawLine( Offset(x, midY - lineHeight), Offset(x, midY + lineHeight), paint, ); } } @override bool shouldRepaint(covariant WaveformPainter oldDelegate) { // 仅当振幅列表变化时重绘,优化性能 if (oldDelegate.amplitudes.length != amplitudes.length) return true; for (int i = 0; i < amplitudes.length; i++) { if (oldDelegate.amplitudes[i] != amplitudes[i]) return true; } return false; } }
关键修改说明:
- 波形结构调整:以画布垂直中线为基准,每个振幅值对应一条上下对称的竖线,竖线高度由振幅值决定,匹配目标的柱状波形样式。
- 动态颜色映射:通过渐变将振幅值(0-1区间)映射到不同颜色,振幅越大颜色越偏向高亮色,直观反映音量变化。
- 性能优化:重写
shouldRepaint方法,仅当振幅数据实际变化时触发重绘,避免不必要的画布刷新。 - 边界处理:使用
clamp方法限制振幅值在0-1区间,防止绘制内容超出画布范围。
内容的提问来源于stack exchange,提问作者Naveen Kumar
相关产品推荐
相关产品推荐

