Flutter二维码扫描插件zxing_scanner的使用
Flutter二维码扫描插件zxing_scanner的使用
ZXing Scanner(Dart)
这是一个可以嵌入到Flutter应用中的条形码扫描组件。它在所有平台上都使用了zxing-dart。
ZXing Dart | ZXing Widget | ZXing Scanner |
---|---|---|
Features
- ✅ 从摄像头扫描(支持Android、iOS、Web)*
- ✅ 从图像文件扫描
注意: 从摄像头扫描需要平台支持摄像头功能。目前摄像头插件支持Android、iOS和Web。在某些移动设备浏览器上获取摄像头时可能会出现错误,详见 camera fix for web。
Getting started
flutter pub add zxing_scanner
Usage
从摄像头扫描
ScanView(
onResult: (List<Result> results),
)
从图像文件扫描
List<Result> results = await scanImage(await file.readAsBytes());
Additional information
此包依赖于 zxing_lib,这是一个纯Dart版本的ZXing库。
示例代码
以下是一个完整的示例代码,展示了如何使用zxing_scanner
插件从摄像头和图像文件中扫描二维码。
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:zxing_scanner/zxing_scanner.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Zxing Scanner Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Zxing Scanner Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
ScanController controller = ScanController();
void _startScan() {
controller.start();
}
void alert(String message) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(message),
actions: [
ElevatedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text('OK'),
)
],
);
},
);
}
void showResult(List<Result>? results) {
if (results?.isEmpty ?? true) {
alert('未识别到二维码');
} else {
alert(
'共识别出${results!.length}个二维码\n${results.map((e) => e.text).join('\n')}',
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: ScanView(
autoStart: false,
controller: controller,
onResult: showResult,
child: Stack(
children: [
Positioned(
right: 0,
top: 0,
child: Padding(
padding: const EdgeInsets.only(right: 16, top: 16),
child: GestureDetector(
onTap: () async {
Feedback.forTap(context);
controller.stop();
final XFile? image = await ImagePicker()
.pickImage(source: ImageSource.gallery);
if (image != null) {
final results =
await scanImage(await image.readAsBytes());
showResult(results);
}
},
behavior: HitTestBehavior.opaque,
child: const Icon(
Icons.image,
color: Colors.blue,
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: IconButton(
style: IconButton.styleFrom(backgroundColor: Colors.white),
onPressed: _startScan,
icon: const Icon(
Icons.camera,
color: Colors.blue,
),
),
),
)
],
),
),
);
}
}
说明
- 导入依赖:首先确保在
pubspec.yaml
文件中添加了zxing_scanner
依赖。 - 创建扫描控制器:使用
ScanController
来控制扫描视图的启动和停止。 - 显示扫描结果:通过
onResult
回调函数处理扫描结果,并显示在对话框中。 - 从摄像头扫描:点击底部的相机图标启动摄像头扫描。
- 从图像文件扫描:点击右上角的图片图标选择图像文件进行扫描。
希望这个示例能帮助你快速上手使用zxing_scanner
插件!
更多关于Flutter二维码扫描插件zxing_scanner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter二维码扫描插件zxing_scanner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用zxing_scanner
插件进行二维码扫描的详细代码示例。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加zxing_scanner
依赖:
dependencies:
flutter:
sdk: flutter
zxing_scanner: ^3.0.0 # 请检查最新版本号并替换
2. 导入包
在你的Flutter项目的Dart文件中(例如main.dart
),导入zxing_scanner
包:
import 'package:flutter/material.dart';
import 'package:zxing_scanner/zxing_scanner.dart';
import 'package:zxing_scanner/camera_access.dart';
3. 创建扫描页面
创建一个扫描页面,例如ScanPage
,其中包含一个ZXingScannerWidget
:
class ScanPage extends StatefulWidget {
@override
_ScanPageState createState() => _ScanPageState();
}
class _ScanPageState extends State<ScanPage> implements ZXingScannerListener {
ZXingScanner? _scanner;
Result? _result;
bool? _isScanning;
@override
void initState() {
super.initState();
_scanner = ZXingScanner.builder()
.setFormats(DefaultFormats)
.setBeepEnabled(true)
.setAutoFocus(true)
.setOrientationLocked(false)
.setCameraId(0) // 使用后置摄像头,1为前置摄像头
.build()..start();
_isScanning = true;
}
@override
void dispose() {
_scanner?.stop();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('二维码扫描'),
),
body: _result == null
? ZXingScannerPage(
titles: '扫描二维码/条码',
showFlash: true,
androidCameraPermissionOptions: AndroidCameraPermissionOptions(
title: '摄像头权限',
message: '该应用需要摄像头权限以扫描二维码。',
positiveButton: '确定',
negativeButton: '取消',
),
iosCameraPermissionOptions: IosCameraPermissionOptions(
message: '该应用需要摄像头权限以扫描二维码。',
),
onCapture: (Result result) {
// 扫描成功后的处理逻辑
setState(() {
_result = result;
_isScanning = false;
});
Navigator.of(context).pop(); // 关闭扫描页面
},
onScanError: (String errorMessage) {
print('扫描错误: $errorMessage');
},
onCameraError: (String errorMessage, dynamic errorCode) {
print('摄像头错误: $errorMessage');
},
onPermissionDenied: (denied, permanentlyDenied) {
print('权限被拒绝: $denied, 永久拒绝: $permanentlyDenied');
if (permanentlyDenied) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('权限被拒绝'),
content: Text('您需要授予摄像头权限才能扫描二维码。'),
actions: <Widget>[
FlatButton(
child: Text('打开设置'),
onPressed: () {
// 引导用户到系统设置
CameraAccess.openAppSettings();
},
),
],
);
},
);
}
},
)
: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('扫描结果: ${_result?.text}'),
ElevatedButton(
onPressed: () {
// 重置扫描结果并重新开始扫描
setState(() {
_result = null;
_isScanning = true;
_scanner?.start();
});
Navigator.of(context).popAndPushNamed('/scan');
},
child: Text('重新扫描'),
),
],
),
),
);
}
@override
void onScanSuccess(Result result) {
// 扫描成功时的回调(可选,已在onCapture中处理)
}
@override
void onScanFailed(Exception e) {
// 扫描失败时的回调
}
@override
void onCameraClosed() {
// 摄像头关闭时的回调
}
}
4. 配置路由
在你的路由配置中添加ScanPage
,例如在main.dart
的MaterialApp
中:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
routes: {
'/': (context) => HomePage(),
'/scan': (context) => ScanPage(),
},
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('主页'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).pushNamed('/scan');
},
child: Text('开始扫描'),
),
),
);
}
}
5. 运行项目
确保你已经正确配置了Android和iOS的摄像头权限,然后运行你的Flutter项目。你应该能够看到一个按钮,点击后可以进入扫描页面,并扫描二维码或条码。
这样,你就完成了在Flutter项目中使用zxing_scanner
插件进行二维码扫描的基本实现。