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

如何在flutter_sound录音时在Text组件中显示计时器?

实现Flutter Sound录音时的实时计时器显示

要实现录音时实时更新计时器并展示在指定Text组件中,你需要借助StatefulWidget管理状态,并用Timer.periodic来触发每秒的计时更新,核心实现如下:

完整代码示例

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:flutter_sound_platform_interface/flutter_sound_recorder_platform_interface.dart';

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

  @override
  State<RecordingTimerWidget> createState() => _RecordingTimerWidgetState();
}

class _RecordingTimerWidgetState extends State<RecordingTimerWidget> {
  FlutterSoundRecorder? _voiceRecorder;
  final String _voicePath = "recording.aac";
  final Codec _codec = Codec.aacMP4;
  
  Timer? _recordingTimer;
  int _secondsElapsed = 0;
  String recordingTime = "00:00";

  // 将累计秒数格式化为 mm:ss 格式
  String _formatTime(int seconds) {
    final minutes = seconds ~/ 60;
    final remainingSeconds = seconds % 60;
    return "${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}";
  }

  Future<void> startRecording() async {
    // 初始化录音器(如果未初始化)
    _voiceRecorder ??= FlutterSoundRecorder();
    await _voiceRecorder!.openRecorder();

    await _voiceRecorder!.startRecorder(
      toFile: _voicePath,
      codec: _codec,
    );

    // 重置计时状态
    setState(() {
      _secondsElapsed = 0;
      recordingTime = _formatTime(_secondsElapsed);
    });

    // 启动每秒触发的计时器
    _recordingTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
      setState(() {
        _secondsElapsed++;
        recordingTime = _formatTime(_secondsElapsed);
      });
    });
  }

  Future<void> stopRecording() async {
    await _voiceRecorder!.stopRecorder();
    // 停止计时器,避免内存泄漏
    _recordingTimer?.cancel();
    _recordingTimer = null;
  }

  @override
  void dispose() {
    // 页面销毁时清理计时器和录音器
    _recordingTimer?.cancel();
    _voiceRecorder?.closeRecorder();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text(
          recordingTime,
          textAlign: TextAlign.center,
          style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w100),
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(onPressed: startRecording, child: const Text("开始录音")),
            const SizedBox(width: 16),
            ElevatedButton(onPressed: stopRecording, child: const Text("停止录音")),
          ],
        )
      ],
    );
  }
}

关键实现说明

  • 状态管理:用StatefulWidget维护计时相关变量,通过setState触发Text组件的UI更新
  • 计时器触发:使用Timer.periodic每秒更新一次累计秒数,并重新格式化时间字符串
  • 内存安全:停止录音时必须取消计时器,同时在dispose方法中清理录音器和计时器实例,防止内存泄漏
  • 时间格式化:通过_formatTime函数将原始秒数转换为用户易读的mm:ss格式

内容的提问来源于stack exchange,提问作者Mohammad Bahadori

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:08:15