Flutter使用qr_code_scanner跳转扫码页后摄像头预览黑屏问题
qr_code_scanner跳转扫码页黑屏问题解决方案
问题根因
qr_code_scanner 0.5.2版本存在摄像头资源生命周期与页面路由不绑定的问题,跳转页面时前序页面未释放摄像头资源、或扫码页初始化时资源未就绪,就会出现预览区域黑屏,需要手动重启摄像头才能正常工作。
修复步骤
1. 确认平台基础配置
- 安卓端:在
android/app/src/main/AndroidManifest.xml中添加相机权限声明,且确保minSdkVersion >= 20<uses-permission android:name="android.permission.CAMERA" /> - iOS端:在
ios/Runner/Info.plist中添加相机权限使用说明<key>NSCameraUsageDescription</key> <string>需要访问相机以扫描二维码</string>
2. 调整扫码页生命周期逻辑
核心是主动控制摄像头初始化时机,页面销毁时强制释放资源,初始化完成后主动重启一次摄像头避免黑屏:
import 'package:qr_code_scanner/qr_code_scanner.dart'; import 'package:permission_handler/permission_handler.dart'; class QRViewApp extends StatefulWidget { const QRViewApp({super.key}); @override State<QRViewApp> createState() => _QRViewAppState(); } class _QRViewAppState extends State<QRViewApp> { final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); QRViewController? controller; bool _isCameraReady = false; @override void initState() { super.initState(); // 等页面挂载完成、权限申请通过后再初始化相机 WidgetsBinding.instance.addPostFrameCallback((_) async { var cameraStatus = await Permission.camera.request(); if (cameraStatus.isGranted) { setState(() => _isCameraReady = true); } }); } @override void dispose() { // 页面销毁必须主动释放控制器,避免资源占锁 controller?.dispose(); super.dispose(); } @override void reassemble() { super.reassemble(); // 适配热重载场景的摄像头重启逻辑 if (Theme.of(context).platform == TargetPlatform.android) { controller?.pauseCamera(); } controller?.resumeCamera(); } @override Widget build(BuildContext context) { return Scaffold( body: _isCameraReady ? QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, ) : const Center(child: CircularProgressIndicator()), ); } void _onQRViewCreated(QRViewController controller) { this.controller = controller; // 初始化完成后主动重启一次摄像头,解决启动黑屏问题 if (Theme.of(context).platform == TargetPlatform.android) { controller.pauseCamera(); } controller.resumeCamera(); // 扫码结果处理逻辑 controller.scannedDataStream.listen((barcode) { // 处理识别到的二维码内容 }); } }
3. 调整跳转逻辑
如果跳转前的页面也持有摄像头相关资源,跳转前必须先释放资源再执行路由跳转:
// 先释放前序页面的摄像头资源 await previousCameraController?.dispose(); if (mounted) { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const qrScreen.QRViewApp()), ); }
备选方案
如果上述修改仍未解决问题,可将qr_code_scanner依赖升级到1.0以上版本,该版本已官方修复了生命周期绑定导致的启动黑屏问题。
内容的提问来源于stack exchange,提问作者Xabah
相关产品推荐
相关产品推荐

