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

Flutter条码扫描完成后如何在扫描页中央显示ProgressIndicator并调用API

问题原因
  • startBarcodeScanStream方法逻辑错误:你监听了条码扫描流,但没有等待流返回结果就直接返回了变量,Future会立即执行完成,FutureBuilder刚渲染就进入了ConnectionState.done状态,自然不会按预期显示加载指示器。
  • 状态更新逻辑缺失:你没有使用状态变量控制加载指示器的显隐,且在builder方法中直接调用getGoodsData接口,每次组件重绘都会重复触发接口请求,逻辑不符合要求。
  • FutureBuilder使用场景错误:你的需求是「扫描完成后才显示加载、调用接口」,而FutureBuilder是等待异步任务完成后渲染UI,逻辑顺序完全相反。
修复方案

首先将当前组件改为StatefulWidget,按以下逻辑调整代码:

  1. 定义状态变量控制加载状态、存储扫描结果
  2. 在initState中初始化条码扫描流,不要在build方法中初始化扫描逻辑,避免重复创建扫描实例
  3. 扫描到有效条码后,先更新状态显示加载指示器,再执行接口请求,请求结束后更新状态隐藏加载指示器
  4. 布局使用Stack层叠加载指示器,扫描界面正常渲染的同时,加载时居中显示指示器
class BarcodeScanPage extends StatefulWidget {
  const BarcodeScanPage({super.key});

  @override
  State<BarcodeScanPage> createState() => _BarcodeScanPageState();
}

class _BarcodeScanPageState extends State<BarcodeScanPage> {
  // 控制加载指示器显隐
  bool _isLoading = false;

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

  Future<void> _initBarcodeScan() async {
    FlutterBarcodeScanner.getBarcodeStreamReceiver(
            '#ff6666', 'Cancel', true, ScanMode.BARCODE)
        .listen((barcode) async {
      if (!mounted) return;
      // 扫描取消直接返回
      if (barcode == "-1") {
        Navigator.pop(context);
        return;
      }
      // 扫描到有效条码,显示加载指示器
      setState(() {
        _isLoading = true;
      });
      try {
        // 调用接口请求商品数据
        await getGoodsData(barcode);
        // 接口请求成功后的逻辑,比如跳转页面、展示数据
      } catch (e) {
        // 接口报错处理逻辑,比如提示用户扫描失败
      } finally {
        // 无论成功失败,都隐藏加载指示器
        if (mounted) {
          setState(() {
            _isLoading = false;
          });
        }
      }
    });
  }

  // 你的接口请求方法
  Future<void> getGoodsData(String barcode) async {
    // 执行你的API请求逻辑
    await Future.delayed(const Duration(seconds: 2)); // 模拟接口请求示例
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.transparent,
        body: Stack(
          children: [
            // 这里替换为你的扫描界面原有布局内容
            const Center(child: Text("条码扫描界面", style: TextStyle(color: Colors.white, fontSize: 18),)),
            // 加载状态为true时显示加载指示器
            if (_isLoading)
              const Center(
                child: CircularProgressIndicator(),
              )
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:39:04