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

Flutter如何实现长按GestureDetector后滑动麦克风图标取消录音的UI效果

实现方案

首先在你的State类中新增两个成员变量,用于标记取消状态和判定取消的滑动阈值:

// 标记是否触发取消录音
bool _isCancelRecording = false;
// 取消阈值,滑动距离超过该值即判定为取消,可根据实际需求调整数值
final double _cancelOffsetThreshold = 70;

新增取消录音的处理方法,用于滑动取消时停止录音、删除临时文件、重置状态:

Future<void> cancelRecord() async {
  await _audioRecorder?.stop();
  // 删除未上传的临时录音文件
  if(_filePath != null) {
    final tempFile = File(_filePath!);
    if(tempFile.existsSync()) {
      tempFile.deleteSync();
    }
  }
  setState(() {
    _isRecording = false;
    _isCancelRecording = false;
    _isRecorded = false;
    Fluttertoast.showToast(msg: '已取消录音');
  });
}

替换原有的GestureDetector代码,新增滑动监听逻辑、修改抬手后的判定逻辑,同时同步调整UI状态反馈:

GestureDetector(
  onLongPress: () async {
    // 每次长按开始前重置取消标记
    _isCancelRecording = false;
    await pressStart();
  },
  // 监听长按过程中的滑动事件
  onLongPressMoveUpdate: (details) {
    // 此处判断任意方向滑动超过阈值即触发取消,如需仅上滑取消可改为 details.offsetFromOrigin.dy < -_cancelOffsetThreshold
    if (details.offsetFromOrigin.distance.abs() > _cancelOffsetThreshold) {
      if(!_isCancelRecording) {
        setState(() {
          _isCancelRecording = true;
        });
        Fluttertoast.showToast(msg: '松开即可取消录音');
      }
    } else {
      if(_isCancelRecording) {
        setState(() {
          _isCancelRecording = false;
        });
        Fluttertoast.showToast(msg: '松开完成录音');
      }
    }
  },
  onLongPressUp: () async {
    // 若已触发取消标记则走取消逻辑,不走原有上传流程
    if(_isCancelRecording) {
      await cancelRecord();
      return;
    }
    // 原有正常结束录音的逻辑保持不变
    await pressUp();
    Future.delayed(const Duration(milliseconds: 100), () {
      setState(() {
        _onFileUploadButtonPressed();
        _onRecordAgainButtonPressed();
      });
    });
  },
  child: _isRecording != true
      ? Container(
          height: 55,
          width: 53,
          child: const Center(
            child: Icon(
              Icons.mic,
              size: 30,
              color: Colors.white,
            ),
          ),
          decoration: BoxDecoration(
              boxShadow: const [
                BoxShadow(
                    offset: Offset(0, 10),
                    blurRadius: 10,
                    color: Colors.grey)
              ],
              color: _isCancelRecording ? Colors.grey : Colors.black,
              shape: BoxShape.circle),
        )
      : Container(
          height: 90,
          width: 90,
          child: Center(
            child: Container(
              decoration: BoxDecoration(
                  boxShadow: const [
                    BoxShadow(
                        offset: Offset(0, 10),
                        blurRadius: 100,
                        color: Colors.grey)
                  ],
                  color: _isCancelRecording ? Colors.grey[300] : Colors.red[300],
                  shape: BoxShape.circle),
              child: Icon(
                _isCancelRecording ? Icons.delete : Icons.pause_circle_filled,
                size: 60,
                color: _isCancelRecording ? Colors.grey : Colors.red,
              ),
            ),
          ),
          decoration: BoxDecoration(
              boxShadow: const [
                BoxShadow(
                    offset: Offset(0, 10),
                    blurRadius: 10,
                    color: Colors.grey)
              ],
              color: _isCancelRecording ? Colors.grey : Colors.red,
              shape: BoxShape.circle),
        )
),

补充说明

  • 可自行调整_cancelOffsetThreshold的数值适配不同屏幕的操作手感
  • 如需限定仅特定方向滑动触发取消,修改onLongPressMoveUpdate中的偏移判定条件即可
  • 代码中同步增加了滑动到取消区域的UI反馈,可根据设计需求自行调整样式

内容的提问来源于stack exchange,提问作者samet demirtop

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 15:57:01