Flutter二维码扫描插件qrscan的使用
Flutter二维码扫描插件qrscan的使用
简介
qrscan
是一个Flutter插件,用于扫描和生成二维码。它支持Android平台,并且可以解析条形码和二维码,同时具备闪光灯控制、权限申请等功能。
- GitHub: github
- License: MIT License
权限配置
在AndroidManifest.xml
中添加以下权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
安装
在pubspec.yaml
文件中添加依赖:
dependencies:
qrscan: ^0.3.3
使用示例
基本用法
扫描二维码或条形码
import 'package:qrscan/qrscan.dart' as scanner;
String cameraScanResult = await scanner.scan();
解析图片中的二维码或条形码
String photoScanResult = await scanner.scanPhoto();
根据指定路径解析图片中的二维码或条形码
String barcode = await scanner.scanPath(path);
根据字节数组解析二维码或条形码
Uint8List bytes = file.readAsBytesSync();
String barcode = await scanner.scanBytes(bytes);
生成二维码
Uint8List result = await scanner.generateBarCode('https://github.com/leyan95/qrcode_scanner');
完整示例Demo
下面是一个完整的Flutter应用程序,展示了如何使用qrscan
插件进行二维码的扫描与生成。
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:qrscan/qrscan.dart' as scanner;
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Uint8List bytes = Uint8List(0);
TextEditingController _inputController;
TextEditingController _outputController;
@override
initState() {
super.initState();
this._inputController = new TextEditingController();
this._outputController = new TextEditingController();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey[300],
body: Builder(
builder: (BuildContext context) {
return ListView(
children: <Widget>[
_qrCodeWidget(this.bytes, context),
Container(
color: Colors.white,
child: Column(
children: <Widget>[
TextField(
controller: this._inputController,
keyboardType: TextInputType.url,
textInputAction: TextInputAction.go,
onSubmitted: (value) => _generateBarCode(value),
decoration: InputDecoration(
prefixIcon: Icon(Icons.text_fields),
helperText:
'Please input your code to generate qrcode image.',
hintText: 'Please Input Your Code',
hintStyle: TextStyle(fontSize: 15),
contentPadding:
EdgeInsets.symmetric(horizontal: 7, vertical: 15),
),
),
SizedBox(height: 20),
TextField(
controller: this._outputController,
maxLines: 2,
decoration: InputDecoration(
prefixIcon: Icon(Icons.wrap_text),
helperText:
'The barcode or qrcode you scan will be displayed in this area.',
hintText:
'The barcode or qrcode you scan will be displayed in this area.',
hintStyle: TextStyle(fontSize: 15),
contentPadding:
EdgeInsets.symmetric(horizontal: 7, vertical: 15),
),
),
SizedBox(height: 20),
this._buttonGroup(),
SizedBox(height: 70),
],
),
),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => _scanBytes(),
tooltip: 'Take a Photo',
child: const Icon(Icons.camera_alt),
),
),
);
}
Widget _qrCodeWidget(Uint8List bytes, BuildContext context) {
return Padding(
padding: EdgeInsets.all(20),
child: Card(
elevation: 6,
child: Column(
children: <Widget>[
Container(
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
Icon(Icons.verified_user, size: 18, color: Colors.green),
Text(' Generate Qrcode', style: TextStyle(fontSize: 15)),
Spacer(),
Icon(Icons.more_vert, size: 18, color: Colors.black54),
],
),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 9),
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(4), topRight: Radius.circular(4)),
),
),
Padding(
padding:
EdgeInsets.only(left: 40, right: 40, top: 30, bottom: 10),
child: Column(
children: <Widget>[
SizedBox(
height: 190,
child: bytes.isEmpty
? Center(
child: Text('Empty code ... ',
style: TextStyle(color: Colors.black38)),
)
: Image.memory(bytes),
),
Padding(
padding: EdgeInsets.only(top: 7, left: 25, right: 25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Expanded(
flex: 5,
child: GestureDetector(
child: Text(
'remove',
style:
TextStyle(fontSize: 15, color: Colors.blue),
textAlign: TextAlign.left,
),
onTap: () =>
this.setState(() => this.bytes = Uint8List(0)),
),
),
Text('|',
style:
TextStyle(fontSize: 15, color: Colors.black26)),
Expanded(
flex: 5,
child: GestureDetector(
onTap: () async {
final success =
await ImageGallerySaver.saveImage(this.bytes);
SnackBar snackBar;
if (success) {
snackBar = new SnackBar(
content: new Text('Successful Preservation!'));
Scaffold.of(context).showSnackBar(snackBar);
} else {
snackBar = new SnackBar(
content: new Text('Save failed!'));
}
},
child: Text(
'save',
style:
TextStyle(fontSize: 15, color: Colors.blue),
textAlign: TextAlign.right,
),
),
),
],
),
)
],
),
),
Divider(height: 2, color: Colors.black26),
Container(
child: Row(
children: <Widget>[
Icon(Icons.history, size: 16, color: Colors.black38),
Text(' Generate History',
style: TextStyle(fontSize: 14, color: Colors.black38)),
Spacer(),
Icon(Icons.chevron_right, size: 16, color: Colors.black38),
],
),
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 9),
)
],
),
),
);
}
Widget _buttonGroup() {
return Row(
children: <Widget>[
Expanded(
flex: 1,
child: SizedBox(
height: 120,
child: InkWell(
onTap: () => _generateBarCode(this._inputController.text),
child: Card(
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Image.asset('images/generate_qrcode.png'),
),
Divider(height: 20),
Expanded(flex: 1, child: Text("Generate")),
],
),
),
),
),
),
Expanded(
flex: 1,
child: SizedBox(
height: 120,
child: InkWell(
onTap: _scan,
child: Card(
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Image.asset('images/scanner.png'),
),
Divider(height: 20),
Expanded(flex: 1, child: Text("Scan")),
],
),
),
),
),
),
Expanded(
flex: 1,
child: SizedBox(
height: 120,
child: InkWell(
onTap: _scanPhoto,
child: Card(
child: Column(
children: <Widget>[
Expanded(
flex: 2,
child: Image.asset('images/albums.png'),
),
Divider(height: 20),
Expanded(flex: 1, child: Text("Scan Photo")),
],
),
),
),
),
),
],
);
}
Future _scan() async {
await Permission.camera.request();
String barcode = await scanner.scan();
if (barcode == null) {
print('nothing return.');
} else {
this._outputController.text = barcode;
}
}
Future _scanPhoto() async {
await Permission.storage.request();
String barcode = await scanner.scanPhoto();
this._outputController.text = barcode;
}
Future _scanPath(String path) async {
await Permission.storage.request();
String barcode = await scanner.scanPath(path);
this._outputController.text = barcode;
}
Future _scanBytes() async {
File file = await ImagePicker().getImage(source: ImageSource.camera).then((picked) {
if (picked == null) return null;
return File(picked.path);
});
if (file == null) return;
Uint8List bytes = file.readAsBytesSync();
String barcode = await scanner.scanBytes(bytes);
this._outputController.text = barcode;
}
Future _generateBarCode(String inputCode) async {
Uint8List result = await scanner.generateBarCode(inputCode);
this.setState(() => this.bytes = result);
}
}
支持的功能
- ✅ 扫描条形码
- ✅ 扫描二维码
- ✅ 控制闪光灯
- ✅ 申请相机权限
- ✅ 从相册中选择条形码或二维码图片进行解析
- ✅ 根据字节数组解析二维码或条形码
- ✅ 根据指定路径解析图片中的二维码或条形码
- ✅ 根据光线强度显示闪光灯开关按钮
- ✅ 生成二维码
待办事项
- [] 支持iOS (example builds, but invoking scanner does not return)
- [] 提供iOS设置文档(如果需要)
许可证
分布式许可为MIT许可证。详情参见LICENSE。
关于
创建者:Shusheng
致谢
特别感谢JetBrains提供的开源免费许可证!
更多关于Flutter二维码扫描插件qrscan的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter二维码扫描插件qrscan的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用qrscan
插件进行二维码扫描的一个示例。请注意,qrscan
插件可能不是Flutter社区中最常用或最新的二维码扫描插件,因此我会使用更广泛认可的qr_code_scanner
插件作为替代,因为它具有更好的支持和功能。不过,如果你特别需要qrscan
插件的代码,请告知,但基于其文档和社区支持情况,我建议使用qr_code_scanner
。
使用 qr_code_scanner
插件进行二维码扫描
- 添加依赖
首先,在你的pubspec.yaml
文件中添加qr_code_scanner
依赖:
dependencies:
flutter:
sdk: flutter
qr_code_scanner: ^0.5.4 # 请检查最新版本号
然后运行flutter pub get
来安装依赖。
- 创建扫描页面
接下来,创建一个新的Flutter页面来处理二维码扫描。这里是一个简单的示例:
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QRScannerPage extends StatefulWidget {
@override
_QRScannerPageState createState() => _QRScannerPageState();
}
class _QRScannerPageState extends State<QRScannerPage> {
final BarcodeDetector? barcodeDetector = FlutterBarcodeScanner.barcodeDetector;
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
QRViewController? controller;
// 在这里处理扫描结果
void _onQRViewCreated(QRViewController qrViewController) {
this.controller = qrViewController;
qrViewController.scannedDataStream.listen((scanResult) {
// 处理扫描到的二维码数据
setState(() {
print("Scanned Data: ${scanResult.code}");
});
// 你可以在这里添加导航逻辑,比如跳转到另一个页面
// Navigator.pushNamed(context, '/result', arguments: scanResult.code);
});
}
@override
Widget build(BuildContext context) {
// 创建一个QRView
return Scaffold(
appBar: AppBar(
title: Text('二维码扫描'),
),
body: Column(
children: <Widget>[
Expanded(
flex: 4,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
reader: barcodeDetector,
),
),
Expanded(
flex: 1,
child: Center(
child: Text(
'扫描二维码...',
style: TextStyle(fontSize: 24),
),
),
),
],
),
);
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
- 导航到扫描页面
在你的主应用页面或其他地方添加导航逻辑,以便用户可以访问这个扫描页面:
import 'package:flutter/material.dart';
import 'qr_scanner_page.dart'; // 假设你的文件名是qr_scanner_page.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter二维码扫描示例'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => QRScannerPage()),
);
},
child: Text('扫描二维码'),
),
),
),
);
}
}
这个示例展示了如何使用qr_code_scanner
插件在Flutter应用中实现二维码扫描功能。请确保你已经在AndroidManifest.xml
和Info.plist
中添加了必要的相机权限。如果你确实需要使用qrscan
插件,并且需要具体的代码示例,请告知,但通常建议使用更广泛支持的插件。