You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 02:20:22