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

如何在Flutter中实现类似ChatGPT应用的语音气泡动画

在Flutter中实现类似ChatGPT语音对话的流畅动画

这类动画核心是模拟语音波动的动态波形效果,通过控制一组矩形条的高度、透明度变化,配合循环动画驱动来实现流畅的视觉表现。以下是具体实现方案:

1. 基础波形动画实现

先创建一个可复用的波形动画组件,通过AnimationController循环驱动,随机更新波形条高度模拟语音波动:

class VoiceWaveAnimation extends StatefulWidget {
  const VoiceWaveAnimation({super.key});

  @override
  State<VoiceWaveAnimation> createState() => _VoiceWaveAnimationState();
}

class _VoiceWaveAnimationState extends State<VoiceWaveAnimation> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  final List<double> _waveHeights = List.generate(8, (_) => 0.2); // 初始高度比例

  @override
  void initState() {
    super.initState();
    // 初始化循环动画控制器
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 350),
    )..repeat();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context, child) {
        // 每帧随机更新部分波形条高度,模拟语音波动
        for (int i = 0; i < _waveHeights.length; i++) {
          if (Random().nextDouble() > 0.6) {
            _waveHeights[i] = Random().nextDouble() * 0.8 + 0.2;
          }
        }
        return Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.end,
          children: List.generate(_waveHeights.length, (index) {
            return Container(
              margin: const EdgeInsets.symmetric(horizontal: 2),
              width: 4,
              height: _waveHeights[index] * 30, // 总高度30px,按比例缩放
              decoration: BoxDecoration(
                color: Colors.grey[600],
                borderRadius: BorderRadius.circular(2),
              ),
            );
          }),
        );
      },
    );
  }
}

2. 优化流畅度与真实感

  • 用AnimatedBuilder替代全局setState,减少不必要的组件重绘,提升动画流畅度
  • 调整动画周期(350ms)和随机更新阈值(0.6),让波动节奏更贴近真实语音的起伏
  • 添加透明度和颜色变化,增强视觉层次感:
// 修改AnimatedBuilder内的波形条构建代码
return Opacity(
  opacity: _waveHeights[index] > 0.5 ? 1.0 : 0.6,
  child: Container(
    margin: const EdgeInsets.symmetric(horizontal: 2),
    width: 4,
    height: _waveHeights[index] * 30,
    decoration: BoxDecoration(
      color: _waveHeights[index] > 0.7 ? Colors.blue : Colors.grey[600],
      borderRadius: BorderRadius.circular(2),
    ),
  ),
);

3. 适配语音状态切换

添加控制方法,实现"开始语音-启动动画"、"结束语音-停止并重置动画"的逻辑:

// 在_VoiceWaveAnimationState类中添加
void startAnimation() {
  if (!_controller.isAnimating) {
    _controller.repeat();
  }
}

void stopAnimation() {
  _controller.stop();
  setState(() {
    _waveHeights.fillRange(0, _waveHeights.length, 0.2); // 重置到初始高度
  });
}

外部可通过GlobalKey获取组件状态,配合语音按钮的点击/长按事件调用这两个方法。

内容的提问来源于stack exchange,提问作者Devarsh Ukani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:12:38