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

如何在Flutter中实现此类音频录制动画效果?

在Flutter中实现音频录制波纹动画效果

下面是实现图中音频录制动画的具体方案,核心分为波纹扩散动画和按钮状态切换两部分:

核心实现思路

  • 用Stack组件叠加录制按钮与多层波纹容器
  • 通过AnimationController控制波纹的缩放与透明度变化
  • 借助GestureDetector处理点击事件,切换录制状态

完整代码示例

import 'package:flutter/material.dart';

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

  @override
  State<AudioRecordAnimation> createState() => _AudioRecordAnimationState();
}

class _AudioRecordAnimationState extends State<AudioRecordAnimation> with SingleTickerProviderStateMixin {
  late AnimationController _animationController;
  late List<Animation<double>> _scaleAnimations;
  late List<Animation<double>> _opacityAnimations;
  bool _isRecording = false;

  // 可自定义的动画参数
  static const int _waveCount = 3;
  static const double _initialSize = 60;
  static const double _maxScale = 2.5;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    )..repeat();

    // 初始化每层波纹的缩放动画
    _scaleAnimations = List.generate(_waveCount, (index) {
      return Tween<double>(begin: 1, end: _maxScale).animate(
        CurvedAnimation(
          parent: _animationController,
          curve: Interval(
            index / _waveCount,
            1.0,
            curve: Curves.easeOut,
          ),
        ),
      );
    });

    // 初始化每层波纹的透明度动画
    _opacityAnimations = List.generate(_waveCount, (index) {
      return Tween<double>(begin: 0.6, end: 0).animate(
        CurvedAnimation(
          parent: _animationController,
          curve: Interval(
            index / _waveCount,
            1.0,
            curve: Curves.easeOut,
          ),
        ),
      );
    });
  }

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

  void _toggleRecording() {
    setState(() {
      _isRecording = !_isRecording;
      _isRecording ? _animationController.repeat() : _animationController.stop();
    });
    // 此处可添加真实音频录制逻辑:
    // _isRecording ? 启动录制 : 停止并保存音频
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: GestureDetector(
        onTap: _toggleRecording,
        child: Stack(
          alignment: Alignment.center,
          children: [
            // 渲染多层波纹
            ...List.generate(_waveCount, (index) {
              return AnimatedBuilder(
                animation: _animationController,
                builder: (context, child) {
                  return Opacity(
                    opacity: _opacityAnimations[index].value,
                    child: Transform.scale(
                      scale: _scaleAnimations[index].value,
                      child: Container(
                        width: _initialSize,
                        height: _initialSize,
                        decoration: BoxDecoration(
                          color: Colors.blue.withOpacity(0.4),
                          shape: BoxShape.circle,
                        ),
                      ),
                    ),
                  );
                },
              );
            }),
            // 中央录制/停止按钮
            Container(
              width: _initialSize,
              height: _initialSize,
              decoration: BoxDecoration(
                color: _isRecording ? Colors.red : Colors.blue,
                shape: BoxShape.circle,
                boxShadow: [
                  BoxShadow(
                    color: Colors.blue.withOpacity(0.3),
                    blurRadius: 8,
                    spreadRadius: 2,
                  ),
                ],
              ),
              child: Icon(
                _isRecording ? Icons.stop : Icons.mic,
                color: Colors.white,
                size: 30,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 组件使用示例
void main() {
  runApp(const MaterialApp(
    home: Scaffold(
      backgroundColor: Colors.white,
      body: AudioRecordAnimation(),
    ),
  ));
}

关键细节说明

  • 波纹时序控制:通过Interval为每层波纹设置不同的动画起始时间,实现波纹依次扩散的递进效果
  • 状态联动:点击按钮时切换录制状态,同步控制动画启停、按钮颜色与图标变化
  • 参数定制:可调整_waveCount(波纹层数)、_initialSize(按钮基础尺寸)、_maxScale(波纹最大缩放比例)来匹配设计需求
  • 功能扩展:在_toggleRecording方法中集成音频录制插件(如audio_recorder)即可实现真实的音频录制功能

内容的提问来源于stack exchange,提问作者kk web

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 08:12:27