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

Flutter扫码时显示progressIndicator及扫码后弹窗的实现咨询

实现方案

你现有代码的核心问题是不应该在build方法中直接调用扫描方法,每次页面重绘都会重复触发扫描逻辑,同时缺少状态变量控制加载指示器的显隐和扫描结果的回调处理。完整实现代码如下:

import 'package:flutter/material.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';

class BarCodeScanner extends StatefulWidget {
  @override
  _BarCodeScannerState createState() => _BarCodeScannerState();
}

class _BarCodeScannerState extends State<BarCodeScanner> {
  // 控制加载指示器显隐的状态变量
  bool _isScanning = false;
  // 存储扫描到的条码值
  String? _scannedBarcode;

  @override
  void initState() {
    super.initState();
    // 页面初始化时触发扫描,不要放在build方法中
    _getBarcodeData();
  }

  Future<void> _getBarcodeData() async {
    // 扫描开始前,显示加载指示器
    if (mounted) {
      setState(() {
        _isScanning = true;
      });
    }
    try {
      FlutterBarcodeScanner.getBarcodeStreamReceiver(
              "#ff6666", "取消", false, ScanMode.DEFAULT)
          .listen((barcode) {
        // 拿到扫描结果后更新状态
        if (mounted) {
          setState(() {
            _isScanning = false;
            _scannedBarcode = barcode;
          });
          // 弹出结果对话框
          _showScanResultDialog(barcode);
        }
      }).onError((error) {
        // 处理扫描错误
        if (mounted) {
          setState(() {
            _isScanning = false;
            _scannedBarcode = "扫描失败:${error.toString()}";
          });
          _showScanResultDialog(_scannedBarcode!);
        }
      });
    } catch (error) {
      if (mounted) {
        setState(() {
          _isScanning = false;
          _scannedBarcode = "扫描失败:${error.toString()}";
        });
        _showScanResultDialog(_scannedBarcode!);
      }
    }
  }

  // 扫描结果弹窗,可自行调整样式匹配配图效果
  void _showScanResultDialog(String result) {
    showDialog(
      context: context,
      barrierDismissible: false,
      builder: (context) => AlertDialog(
        title: const Text("扫描结果"),
        content: Text("扫描到的条码内容:\n$result"),
        actions: [
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              // 如果需要重新扫描可以在这里再次调用_getBarcodeData()
            },
            child: const Text("确认"),
          )
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        // 根据扫描状态显隐加载指示器
        child: _isScanning 
          ? const CircularProgressIndicator()
          : const Text("等待扫描"),
      ),
    );
  }
}

关键逻辑说明

  • 新增_isScanning状态变量控制加载指示器的显隐,扫描开始前设为true,拿到结果或报错后设为false
  • 扫描逻辑移到initState中触发,避免重复调用,所有状态更新前都加了mounted判断防止页面销毁后报错
  • 单独封装_showScanResultDialog方法处理结果弹窗,你可以根据配图的样式自定义弹窗的标题、内容、按钮样式和排版
  • 增加了错误处理逻辑,扫描异常时也会隐藏加载指示器并弹出错误提示

注意事项

使用前请确保已经在pubspec.yaml中引入了flutter_barcode_scanner依赖,并且完成了安卓和iOS端的相机权限配置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:06:04