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
相关产品推荐
相关产品推荐

