Flutter二维码扫描插件barcode_scan3的使用
Flutter二维码扫描插件barcode_scan3的使用
简介
barcode_scan3 是一个用于扫描二维条形码和QR码的Flutter插件。它封装了两个常用的iOS和Android库:
- iOS: MTBBarcodeScanner
- Android: barcodescanner
此插件支持以下功能:
- 扫描二维条形码
- 扫描QR码
- 控制闪光灯
- 权限处理
使用步骤
Android 配置
在使用插件之前,需要在 AndroidManifest.xml 文件中添加相机权限:
<uses-permission android:name="android.permission.CAMERA" />
此外,此插件使用Kotlin编写,因此需要为项目添加Kotlin支持。编辑项目级别的 build.gradle 文件:
buildscript {
ext.kotlin_version = '1.3.61'
// ...
dependencies {
// ...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
// ...
然后编辑应用级别的 build.gradle 文件:
apply plugin: 'kotlin-android'
// ...
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// ...
}
最后,在 pubspec.yaml 文件中添加依赖:
dependencies:
# ...
barcode_scan3: any
运行 flutter packages get 或点击Android Studio中的“Packages get”。
iOS 配置
在iOS上使用时,需要在 Info.plist 文件中添加相机使用描述:
<key>NSCameraUsageDescription</key>
<string>Camera permission is required for barcode scanning.</string>
基本用法
以下是一个简单的示例,展示如何使用 barcode_scan3 插件进行二维码扫描:
import 'package:barcode_scan3/barcode_scan3.dart';
void main() async {
var result = await BarcodeScanner.scan();
print(result.type); // 结果类型(barcode, cancelled, failed)
print(result.rawContent); // 二维码内容
print(result.format); // 二维码格式(枚举)
print(result.formatNote); // 如果扫描到未知格式,则包含说明
}
高级用法
可以传递选项来定制扫描行为:
import 'package:barcode_scan3/barcode_scan3.dart';
void main() async {
var options = ScanOptions(
strings: {
'cancel': '取消',
'flash_on': '打开闪光灯',
'flash_off': '关闭闪光灯',
},
restrictFormat: [BarcodeFormat.qr], // 限制识别的格式
useCamera: 0, // 使用默认摄像头
autoEnableFlash: true, // 启动扫描时开启闪光灯
android: AndroidOptions(
aspectTolerance: 0.5, // 设置宽容度
useAutoFocus: true, // 启用自动对焦
),
);
var result = await BarcodeScanner.scan(options: options);
// 处理扫描结果
}
支持的选项
以下是 ScanOptions 中支持的选项及其说明:
| 选项名称 | 类型 | 描述 | 支持平台 |
|---|---|---|---|
strings.cancel |
String | iOS上的取消按钮文本 | iOS only |
strings.flash_on |
String | 闪光灯开启按钮文本 | iOS + Android |
strings.flash_off |
String | 闪光灯关闭按钮文本 | iOS + Android |
restrictFormat |
BarcodeFormat[] | 限制识别的格式 | iOS + Android |
useCamera |
int | 使用的摄像头索引 | iOS + Android |
autoEnableFlash |
bool | 启动扫描时是否开启闪光灯 | iOS + Android |
android.aspectTolerance |
double | 设置宽容度 | Android only |
android.useAutoFocus |
bool | 是否启用自动对焦 | Android only |
示例代码
以下是一个完整的示例代码,展示了如何实现一个带有自定义选项的二维码扫描界面:
import 'dart:async';
import 'dart:io' show Platform;
import 'package:barcode_scan3/barcode_scan3.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const App());
class App extends StatefulWidget {
const App({Key? key}) : super(key: key);
[@override](/user/override)
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
ScanResult? scanResult;
final _flashOnController = TextEditingController(text: '打开闪光灯');
final _flashOffController = TextEditingController(text: '关闭闪光灯');
final _cancelController = TextEditingController(text: '取消');
var _aspectTolerance = 0.00;
var _numberOfCameras = 0;
var _selectedCamera = -1;
var _useAutoFocus = true;
var _autoEnableFlash = false;
static final _possibleFormats = BarcodeFormat.values.toList()
..removeWhere((e) => e == BarcodeFormat.unknown);
List<BarcodeFormat> selectedFormats = [..._possibleFormats];
[@override](/user/override)
void initState() {
super.initState();
Future.delayed(Duration.zero, () async {
_numberOfCameras = await BarcodeScanner.numberOfCameras;
setState(() {});
});
}
[@override](/user/override)
Widget build(BuildContext context) {
final scanResult = this.scanResult;
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('二维码扫描示例'),
actions: [
IconButton(
icon: const Icon(Icons.camera),
tooltip: '扫描',
onPressed: _scan,
)
],
),
body: ListView(
scrollDirection: Axis.vertical,
shrinkWrap: true,
children: <Widget>[
if (scanResult != null)
Card(
child: Column(
children: <Widget>[
ListTile(
title: const Text('结果类型'),
subtitle: Text(scanResult.type.toString()),
),
ListTile(
title: const Text('原始内容'),
subtitle: Text(scanResult.rawContent),
),
ListTile(
title: const Text('格式'),
subtitle: Text(scanResult.format.toString()),
),
ListTile(
title: const Text('格式说明'),
subtitle: Text(scanResult.formatNote),
),
],
),
),
const ListTile(
title: Text('摄像头选择'),
dense: true,
enabled: false,
),
RadioListTile(
onChanged: (v) => setState(() => _selectedCamera = -1),
value: -1,
title: const Text('默认摄像头'),
groupValue: _selectedCamera,
),
...List.generate(
_numberOfCameras,
(i) => RadioListTile(
onChanged: (v) => setState(() => _selectedCamera = i),
value: i,
title: Text('摄像头 ${i + 1}'),
groupValue: _selectedCamera,
),
),
const ListTile(
title: Text('按钮文本'),
dense: true,
enabled: false,
),
ListTile(
title: TextField(
decoration: const InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
labelText: '闪光灯开启',
),
controller: _flashOnController,
),
),
ListTile(
title: TextField(
decoration: const InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
labelText: '闪光灯关闭',
),
controller: _flashOffController,
),
),
ListTile(
title: TextField(
decoration: const InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.always,
labelText: '取消',
),
controller: _cancelController,
),
),
if (Platform.isAndroid) ...[
const ListTile(
title: Text('Android特定选项'),
dense: true,
enabled: false,
),
ListTile(
title: Text(
'宽容度 (${_aspectTolerance.toStringAsFixed(2)})',
),
subtitle: Slider(
min: -1,
max: 1,
value: _aspectTolerance,
onChanged: (value) {
setState(() {
_aspectTolerance = value;
});
},
),
),
CheckboxListTile(
title: const Text('启用自动对焦'),
value: _useAutoFocus,
onChanged: (checked) {
setState(() {
_useAutoFocus = checked!;
});
},
),
],
const ListTile(
title: Text('其他选项'),
dense: true,
enabled: false,
),
CheckboxListTile(
title: const Text('启动时开启闪光灯'),
value: _autoEnableFlash,
onChanged: (checked) {
setState(() {
_autoEnableFlash = checked!;
});
},
),
const ListTile(
title: Text('条形码格式'),
dense: true,
enabled: false,
),
ListTile(
trailing: Checkbox(
tristate: true,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
value: selectedFormats.length == _possibleFormats.length
? true
: selectedFormats.isEmpty
? false
: null,
onChanged: (checked) {
setState(() {
selectedFormats = [
if (checked ?? false) ..._possibleFormats,
];
});
},
),
dense: true,
enabled: false,
title: const Text('检测条形码格式'),
subtitle: const Text(
'如果全部未选中,则会使用所有可能的平台格式',
),
),
..._possibleFormats.map(
(format) => CheckboxListTile(
value: selectedFormats.contains(format),
onChanged: (i) {
setState(() =>
selectedFormats.contains(format)
? selectedFormats.remove(format)
: selectedFormats.add(format));
},
title: Text(format.toString()),
),
),
],
),
),
);
}
Future<void> _scan() async {
try {
final result = await BarcodeScanner.scan(
options: ScanOptions(
strings: {
'cancel': _cancelController.text,
'flash_on': _flashOnController.text,
'flash_off': _flashOffController.text,
},
restrictFormat: selectedFormats,
useCamera: _selectedCamera,
autoEnableFlash: _autoEnableFlash,
android: AndroidOptions(
aspectTolerance: _aspectTolerance,
useAutoFocus: _useAutoFocus,
),
),
);
setState(() => scanResult = result);
} on PlatformException catch (e) {
setState(() {
scanResult = ScanResult(
type: ResultType.Error,
format: BarcodeFormat.unknown,
rawContent: e.code == BarcodeScanner.cameraAccessDenied
? '用户未授予相机权限!'
: '未知错误: $e',
);
});
}
}
}
更多关于Flutter二维码扫描插件barcode_scan3的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter二维码扫描插件barcode_scan3的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
barcode_scan3 是一个用于 Flutter 的二维码和条形码扫描插件。它基于 Android 的 ZXing 和 iOS 的 MTBBarcodeScanner 库。以下是如何在 Flutter 项目中使用 barcode_scan3 插件的步骤。
1. 添加依赖
首先,在 pubspec.yaml 文件中添加 barcode_scan3 依赖:
dependencies:
flutter:
sdk: flutter
barcode_scan3: ^3.0.0
然后,运行 flutter pub get 以安装依赖。
2. 配置平台
Android 配置
在 android/app/src/main/AndroidManifest.xml 文件中添加相机权限:
<uses-permission android:name="android.permission.CAMERA" />
确保 android/app/build.gradle 中的 minSdkVersion 至少为 21:
defaultConfig {
minSdkVersion 21
targetSdkVersion 30
// 其他配置
}
iOS 配置
在 ios/Runner/Info.plist 文件中添加相机权限描述:
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to scan barcodes.</string>
3. 使用插件
在 Dart 代码中导入 barcode_scan3 插件并使用它来启动扫描。
import 'package:flutter/material.dart';
import 'package:barcode_scan3/barcode_scan3.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BarcodeScanner(),
);
}
}
class BarcodeScanner extends StatefulWidget {
@override
_BarcodeScannerState createState() => _BarcodeScannerState();
}
class _BarcodeScannerState extends State<BarcodeScanner> {
String _scanResult = 'Scan a barcode';
Future<void> _scan() async {
try {
final result = await BarcodeScanner.scan();
setState(() {
_scanResult = result.rawContent ?? 'No data found';
});
} catch (e) {
setState(() {
_scanResult = 'Failed to scan: $e';
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Barcode Scanner'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(_scanResult),
SizedBox(height: 20),
ElevatedButton(
onPressed: _scan,
child: Text('Scan Barcode'),
),
],
),
),
);
}
}
4. 运行项目
确保你的设备或模拟器已连接,然后运行项目:
flutter run
5. 处理扫描结果
扫描完成后,BarcodeScanner.scan() 方法会返回一个 ScanResult 对象,其中包含扫描到的数据。你可以通过 result.rawContent 获取扫描到的字符串。
6. 自定义配置
barcode_scan3 插件允许你自定义扫描界面的样式和行为。你可以在 BarcodeScanner.scan() 方法中传递 ScanOptions 对象来进行配置。例如:
final result = await BarcodeScanner.scan(
options: const ScanOptions(
strings: {
'cancel': 'Cancel',
'flash_on': 'Flash On',
'flash_off': 'Flash Off',
},
autoEnableFlash: false,
),
);
7. 处理权限
在某些情况下,你可能需要手动请求相机权限。你可以使用 permission_handler 插件来处理权限请求。
import 'package:permission_handler/permission_handler.dart';
Future<void> _requestPermission() async {
var status = await Permission.camera.status;
if (!status.isGranted) {
await Permission.camera.request();
}
}

