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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:48:01