Flutter二维码扫描插件qr_code_scanner_plus的使用
Flutter二维码扫描插件qr_code_scanner_plus的使用
描述
qr_code_scanner_plus
是一个基于 qr_code_scanner
库的分支,包含一些额外的维护工作。这个插件可以在Flutter应用程序中嵌入原生视图以进行二维码扫描,同时在iOS和Android上都具有无缝集成的效果。
需要注意的是,由于底层框架(Android上的 zxing 和 iOS 上的 MTBBarcodeScanner)都不再被维护,因此该插件也仅处于维护模式,只会考虑修复错误和进行小幅度增强。开发者正在开发一个新的插件 mobile_scanner,它使用最新的MLKit版本来检测条形码和二维码,并且在Android上使用CameraX,在iOS上使用AVFoundation来获得最佳的相机性能。
使用方法
添加依赖
首先,在您的pubspec.yaml
文件中添加qr_code_scanner_plus
作为依赖项:
dependencies:
qr_code_scanner_plus: ^latest_version # 替换为最新版本号
然后运行flutter pub get
来安装包。
示例代码
下面是一个完整的示例Demo,展示了如何使用qr_code_scanner_plus
创建一个简单的二维码扫描页面。
import 'dart:developer';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
void main() => runApp(const MaterialApp(home: MyHome()));
class MyHome extends StatelessWidget {
const MyHome({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Demo Home Page')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => const QRViewExample(),
));
},
child: const Text('Open QR Scanner'),
),
),
);
}
}
class QRViewExample extends StatefulWidget {
const QRViewExample({Key? key}) : super(key: key);
@override
State<StatefulWidget> createState() => _QRViewExampleState();
}
class _QRViewExampleState extends State<QRViewExample> {
Barcode? result;
QRViewController? controller;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
// 热重载时暂停或恢复摄像头
@override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
}
controller!.resumeCamera();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(
flex: 1,
child: FittedBox(
fit: BoxFit.contain,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
if (result != null)
Text(
'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
else
const Text('Scan a code'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.toggleFlash();
setState(() {});
},
child: FutureBuilder(
future: controller?.getFlashStatus(),
builder: (context, snapshot) {
return Text('Flash: ${snapshot.data}');
},
)),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.flipCamera();
setState(() {});
},
child: FutureBuilder(
future: controller?.getCameraInfo(),
builder: (context, snapshot) {
if (snapshot.data != null) {
return Text(
'Camera facing ${describeEnum(snapshot.data!)}');
} else {
return const Text('loading');
}
},
)),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.pauseCamera();
},
child: const Text('Pause', style: TextStyle(fontSize: 20)),
),
),
Container(
margin: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () async {
await controller?.resumeCamera();
},
child: const Text('Resume', style: TextStyle(fontSize: 20)),
),
)
],
),
],
),
),
)
],
),
);
}
Widget _buildQrView(BuildContext context) {
var scanArea = (MediaQuery.of(context).size.width < 400 ||
MediaQuery.of(context).size.height < 400)
? 150.0
: 300.0;
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) {
setState(() {
result = scanData;
});
});
}
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
if (!p) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('No permission')),
);
}
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
此代码实现了以下功能:
- 打开一个新的页面用于扫描二维码。
- 显示扫描结果,包括条码类型和数据内容。
- 提供了切换闪光灯、翻转摄像头以及暂停/恢复扫描的功能按钮。
平台特定配置
Android 配置
确保您已经更新了Gradle、Kotlin以及Kotlin Gradle Plugin到最新版本,并调整了最低SDK版本。
- 在
android/build.gradle
中将ext.kotlin_version
设置为’1.5.10’及以上。 - 同样在
android/build.gradle
中将classpath 'com.android.tools.build:gradle:
设置为4.2.0
及以上。 - 在
android/gradle/wrapper/gradle-wrapper.properties
中将distributionUrl
设置为gradle-6.9-all.zip
及以上。 - 在
android/app/build.gradle
中将minSdkVersion
设置为20及以上。
iOS 配置
为了使用此插件,请在Info.plist
文件中添加以下键值对:
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan QR codes</string>
此外,如果遇到与Flutter Beta或Dev通道相关的错误,可以尝试通过向gradle.properties
文件添加android.enableDexingArtifactTransform=false
来解决。
注意事项
- Web端支持尚处于早期阶段,目前仅支持扫描二维码,其他类型的条形码和二维条码不被支持。
- 对于Web端,某些特性如闪光灯控制、暂停/恢复等功能尚未实现。
希望这些信息能帮助您顺利地在Flutter项目中集成并使用qr_code_scanner_plus
插件!如果有任何问题或者需要进一步的帮助,请随时提问。
更多关于Flutter二维码扫描插件qr_code_scanner_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter二维码扫描插件qr_code_scanner_plus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用qr_code_scanner_plus
插件来扫描二维码的详细代码案例。
首先,确保你已经在你的pubspec.yaml
文件中添加了qr_code_scanner_plus
依赖项:
dependencies:
flutter:
sdk: flutter
qr_code_scanner_plus: ^1.0.0 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
接下来,你需要配置Android和iOS的权限。对于Android,在android/app/src/main/AndroidManifest.xml
中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
对于iOS,在ios/Runner/Info.plist
中添加以下权限:
<key>NSCameraUsageDescription</key>
<string>需要访问相机来扫描二维码</string>
现在,你可以在你的Flutter项目中编写代码来实现二维码扫描功能。下面是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
import 'package:qr_code_scanner_plus_platform_interface/models/qr_code_result.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: QrCodeScannerScreen(),
);
}
}
class QrCodeScannerScreen extends StatefulWidget {
@override
_QrCodeScannerScreenState createState() => _QrCodeScannerScreenState();
}
class _QrCodeScannerScreenState extends State<QrCodeScannerScreen> {
final QRCodeScannerController _controller = QRCodeScannerController();
bool _isScanning = false;
String? _result;
@override
void initState() {
super.initState();
_controller.initialize().then((_) {
if (mounted) {
setState(() {});
}
_controller.scannedDataStream.listen((qrCodeResult) {
setState(() {
_result = qrCodeResult?.text;
_isScanning = false;
_controller.pauseCamera();
});
});
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('二维码扫描'),
),
body: _isScanning
? Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
flex: 5,
child: QRCodeScanner(
controller: _controller,
overlay: QrScannerOverlayShape(
borderColor: Colors.blue,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
topOffset: 20,
rightOffset: 20,
bottomOffset: 40,
leftOffset: 20,
cutOutSize: 50,
),
),
),
],
)
: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('扫描结果: $_result'),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
setState(() {
_isScanning = true;
_result = null;
_controller.resumeCamera();
});
},
child: Text('重新扫描'),
),
],
),
);
}
}
在这个示例中,我们创建了一个QrCodeScannerScreen
,它使用QRCodeScannerController
来管理二维码扫描器的状态。我们在initState
中初始化控制器,并监听扫描到的数据流。当扫描到二维码时,我们更新状态,停止扫描,并显示结果。
你可以根据需要调整UI和逻辑,例如添加错误处理、优化扫描界面等。希望这个示例对你有帮助!