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

Flutter 3.3.0中qr_code_scanner仅首次可用后续黑屏问题求助

问题解决与二维码扫描包推荐

一、当前黑屏问题的修复方案

你遇到的重复扫描黑屏问题,核心原因是相机资源未正确释放或状态管理混乱,结合你的代码,可通过以下几点修复:

1. 修正扫描成功后的相机状态处理

扫描到结果后直接Navigator.pop(context),会导致相机资源未被正确暂停/释放,再次进入页面时相机无法重新初始化。需要先暂停相机再执行页面跳转:

controller.scannedDataStream.listen((scanData) {
  // 先暂停相机
  controller.pauseCamera();
  setState((){
    result = scanData.code;
  });
  Navigator.pop(context, scanData.code); // 可把结果带回上一页
});

2. 优化生命周期方法中的相机操作

  • 移除initState和build中的controller?.resumeCamera():initState时controller还未初始化,调用无效;build中每次重建都调用会导致相机状态混乱。
  • 给reassemble方法添加空安全判断,避免空指针异常:
@override
void reassemble() {
  super.reassemble();
  if (Platform.isAndroid) {
    controller?.pauseCamera();
    // 延迟恢复相机,避免状态冲突
    Future.delayed(const Duration(milliseconds: 500), () {
      controller?.resumeCamera();
    });
  } else if (Platform.isIOS) {
    controller?.resumeCamera();
  }
}

3. 确保页面销毁时彻底释放资源

在dispose中先停止相机再释放控制器,确保资源完全回收:

@override
void dispose() {
  controller?.stopCamera();
  controller?.dispose();
  super.dispose();
}

完整修改后的代码

class QRScanScreen extends StatefulWidget {
  const QRScanScreen({Key? key}) : super(key: key);

  @override
  State<QRScanScreen> createState() => _QRScanScreenState();
}

class _QRScanScreenState extends State<QRScanScreen> {
  final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
  Barcode? result;
  QRViewController? controller;

  @override
  void reassemble() {
    super.reassemble();
    if (Platform.isAndroid) {
      controller?.pauseCamera();
      Future.delayed(const Duration(milliseconds: 500), () {
        controller?.resumeCamera();
      });
    } else if (Platform.isIOS) {
      controller?.resumeCamera();
    }
  }

  @override
  void dispose() {
    controller?.stopCamera();
    controller?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final cashInBloc = CashInModuleProvider.of(context);
    var scanArea = (MediaQuery.of(context).size.width < 400 ||
            MediaQuery.of(context).size.height < 400)
        ? 150.0
        : 300.0;
    return Scaffold(
      appBar: AppBar(
        title: const Text(TITLE_SCAN_QR_CODE),
      ),
      body: QRView(
        key: qrKey,
        onQRViewCreated: (controller) {
          this.controller = controller;
          controller.scannedDataStream.listen((scanData) {
            // 先暂停相机再返回
            controller.pauseCamera();
            setState((){
              result = scanData.code;
            });
            Navigator.pop(context, scanData.code);
          });
        },
        overlay: QrScannerOverlayShape(
          borderColor: Colors.red,
          borderRadius: 10,
          borderLength: 30,
          borderWidth: 10,
          cutOutSize: scanArea,
        ),
        onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
      ),
    );
  }

  void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
    log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
    if (!p) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('无相机权限')),
      );
    }
  }
}

二、推荐的Flutter二维码扫描包

1. barcode_scan2

  • 基于ZXing库,支持Android/iOS双平台,维护活跃,适配最新系统版本
  • 支持多种条码格式,配置灵活,可自定义扫描界面

2. flutter_barcode_scanner

  • 轻量易用,API简单,快速集成
  • 内置默认扫描界面,适合快速开发需求,支持闪光灯切换

3. mobile_scanner

  • 基于Google的ML Kit,性能优异,支持二维码和条码扫描
  • 对最新Android/iOS版本兼容性好,支持实时扫描和图片扫描

4. qr_flutter

  • 兼具二维码生成和扫描功能,适合需要同时处理生成与扫描的场景
  • 自定义程度高,可调整扫描区域、样式等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 10:45:34