如何使用Flutter制作带自定义聚焦边框的二维码扫描器
Flutter 实现带聚焦边框的内嵌式二维码扫描器方案
你当前使用的flutter_barcode_scanner包调用的是原生全屏扫描页面,不支持自定义内嵌视图和扫描边框,要实现Container内运行、带蓝色聚焦边框的效果,推荐使用支持高度自定义的mobile_scanner包实现,步骤如下:
1. 添加依赖
在pubspec.yaml中添加依赖:
dependencies: flutter: sdk: flutter mobile_scanner: ^3.5.5 # 可替换为最新稳定版
执行flutter pub get安装依赖。
2. 实现带自定义边框的扫描页面
核心逻辑是将扫描视图放在指定大小的Container内,上层叠加自定义的蓝色聚焦边框层,完整代码示例:
import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; class QrScannerPage extends StatefulWidget { const QrScannerPage({super.key}); @override State<QrScannerPage> createState() => _QrScannerPageState(); } class _QrScannerPageState extends State<QrScannerPage> { final MobileScannerController _scannerController = MobileScannerController( formats: [BarcodeFormat.qrCode], // 只识别二维码 autoStart: true, ); // 处理扫码结果 void _handleScanResult(BarcodeCapture capture) { final List<Barcode> barcodes = capture.barcodes; if (barcodes.isNotEmpty) { final String qrCode = barcodes.first.rawValue ?? ''; // 扫码成功后停止扫描 _scannerController.stop(); if (!mounted) return; // 弹出结果弹窗,和你原有逻辑一致 showDialog( context: context, builder: (_) { return Dialog( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Container( height: 300, width: 250, padding: const EdgeInsets.all(20), child: Center(child: Text(qrCode)), ), ); }, ).then((_) { // 关闭弹窗后返回上一页 Navigator.pop(context); }); } } @override void dispose() { _scannerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBar( title: const Text('扫码'), backgroundColor: Colors.white, elevation: 0, ), body: Center( // 你要求的扫描功能运行在Container内,可自定义Container大小 child: Container( width: 300, height: 300, decoration: BoxDecoration( border: Border.all(color: Colors.transparent), borderRadius: BorderRadius.circular(12), ), clipBehavior: Clip.hardEdge, child: Stack( alignment: Alignment.center, children: [ // 扫描视图层 MobileScanner( controller: _scannerController, onDetect: _handleScanResult, ), // 蓝色聚焦边框层 _buildScannerBorder(), ], ), ), ), ); } // 自定义蓝色四角扫描边框 Widget _buildScannerBorder() { const borderColor = Colors.blue; const borderWidth = 3.0; const borderRadius = 8.0; const borderLength = 24.0; return Stack( children: [ // 左上角 Positioned( top: 0, left: 0, child: Container( width: borderLength, height: borderLength, decoration: const BoxDecoration( border: Border( top: BorderSide(color: borderColor, width: borderWidth), left: BorderSide(color: borderColor, width: borderWidth), ), borderRadius: BorderRadius.only(topLeft: Radius.circular(borderRadius)), ), ), ), // 右上角 Positioned( top: 0, right: 0, child: Container( width: borderLength, height: borderLength, decoration: const BoxDecoration( border: Border( top: BorderSide(color: borderColor, width: borderWidth), right: BorderSide(color: borderColor, width: borderWidth), ), borderRadius: BorderRadius.only(topRight: Radius.circular(borderRadius)), ), ), ), // 左下角 Positioned( bottom: 0, left: 0, child: Container( width: borderLength, height: borderLength, decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: borderColor, width: borderWidth), left: BorderSide(color: borderColor, width: borderWidth), ), borderRadius: BorderRadius.only(bottomLeft: Radius.circular(borderRadius)), ), ), ), // 右下角 Positioned( bottom: 0, right: 0, child: Container( width: borderLength, height: borderLength, decoration: const BoxDecoration( border: Border( bottom: BorderSide(color: borderColor, width: borderWidth), right: BorderSide(color: borderColor, width: borderWidth), ), borderRadius: BorderRadius.only(bottomRight: Radius.circular(borderRadius)), ), ), ), ], ); } }
3. 替换原有扫码触发逻辑
把你原来调用scanQRCode方法的逻辑替换为跳转至QrScannerPage即可:
// 原来触发扫码的按钮点击事件修改为 onTap: () => Navigator.push(context, MaterialPageRoute(builder: (context) => const QrScannerPage()))
内容的提问来源于stack exchange,提问作者samit
相关产品推荐
相关产品推荐

