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

Flutter中实现speech_to_text语音转文本追加至TextFormField

Flutter speech_to_text 实现语音识别文本追加到已有内容的解决方案

问题描述

使用speech_to_text插件实现语音转文本功能,识别结果可正常显示在TextFormField中,但再次启动语音识别时,TextFormField内的原有文本会被清空,需求是让新识别的文本追加到原有文本之后。

问题分析

原代码存在两个核心问题:

  1. 每次启动识别时都重复调用_speech.initialize(),这会重置插件状态,可能导致原有文本被意外清空;
  2. 未区分识别过程中的中间结果和最终结果,会导致多次追加重复内容,同时缺少对新旧文本的分隔处理。

解决方案

1. 提前初始化语音识别插件

将插件初始化逻辑移至initState,仅执行一次,避免重复初始化导致的状态重置:

@override
void initState() {
  super.initState();
  _initSpeech();
}

Future<void> _initSpeech() async {
  bool isAvailable = await _speech.initialize();
  if (!isAvailable) {
    setState(() {
      _speechText = 'Speech recognition not available';
      print("not supported");
    });
  }
}

2. 修改语音监听方法

移除重复初始化逻辑,仅在最终识别结果返回时追加文本,并添加空格分隔新旧内容:

Future<void> _listenForSpeech() async {
  if (!_speech.isAvailable) {
    setState(() {
      _speechText = 'Speech recognition not available';
      return;
    });
  }
  
  print("supported");
  bool isListening = await _speech.listen(
    onResult: (result) {
      setState(() {
        _isListening = true;
        // 仅处理最终识别结果,避免重复追加中间内容
        if (result.finalResult) {
          // 若原有文本不为空,添加空格分隔
          if (_textFromSpeechController.text.isNotEmpty) {
            _textFromSpeechController.text += ' ';
          }
          _textFromSpeechController.text += result.recognizedWords;
        }
      });
    },
  );
  if (!isListening) {
    setState(() {
      _speechText = 'Failed to start listening';
    });
  }
}

3. 优化停止监听方法

使用stop()替代cancel(),确保能获取到本次识别的最终结果,而不是直接丢弃:

void _stopVoiceListener() {
  if (_isListening) {
    _isListening = false;
    _speech.stop();
  }
}

效果说明

修改后,再次启动语音识别时,原有文本会被保留,新识别的内容会自动追加到文本末尾,且通过空格分隔保证内容可读性;同时避免了重复初始化和中间结果重复追加的问题。

内容的提问来源于stack exchange,提问作者Rakesh Saini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:17:35