image
介紹
二維碼作為信息的載體,廣泛應(yīng)用于我們生活的方方面面,例如:使用支付寶支付,二維碼加好友,二維碼推廣等等,能舉例的例子多不勝數(shù),而如果你的應(yīng)用支持二維碼的掃描,用戶和體驗將會翻倍的增長,如果你是應(yīng)用的開發(fā)者,歡迎來使用此二維碼掃描插件!并希望能給予項目一個star,謝謝!項目地址:https://github.com/rhymelph/r_scan
使用
你可以在pub.dev網(wǎng)站上面搜索r_scan即可找到該插件,添加下面代碼到pubspec.yaml文件
dependencies:
r_scan: last version
- last version 可以在pub.dev網(wǎng)站搜索
r_scan得到
各設(shè)備注意事項
- Android平臺下
android6.0系統(tǒng)以上請動態(tài)授權(quán),可以結(jié)合permission_handler插件使用,代碼如下:
import 'package:permission_handler/permission_handler.dart';
Future<bool> canReadStorage() async {
if(Platform.isIOS) return true;
var status = await PermissionHandler()
.checkPermissionStatus(PermissionGroup.storage);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
Future<bool> canOpenCamera() async {
var status =
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.camera]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
- IOS平臺下
需要在info.plist文件下添加如下代碼:
<key>NSCameraUsageDescription</key>
<string>掃描二維碼時需要使用您的相機(jī)</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>掃描二維碼時需要訪問您的相冊</string>
<key>io.flutter.embedded_views_preview</key>
<true/>
導(dǎo)包
import 'package:r_scan/r_scan.dart';
1.掃描文件圖片二維碼
final result=await RScan.scanImagePath('你的文件路徑');
if(result.isNotEmpty){
//result 為二維碼內(nèi)容
}
2.掃描圖片鏈接二維碼
final result=await RScan.scanImagePath('你的圖片鏈接');
if(result.isNotEmpty){
//result 為二維碼內(nèi)容
}
3.掃描內(nèi)存圖片二維碼
ByteData data=await rootBundle.load('images/qrCode.png');
final result=await RScan.scanImageMemory(data.buffer.asUint8List());
if(result.isNotEmpty){
//result 為二維碼內(nèi)容
}
4.(NEW)基于Texture使用相機(jī)掃描二維碼/條形碼
- 步驟1:獲取可用相機(jī)
List<RScanCameraDescription> rScanCameras = await availableRScanCameras();;
如果你在main()方法下獲取可用相機(jī),請使用下面代碼
List<RScanCameraDescription> rScanCameras;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
rScanCameras = await availableRScanCameras();
runApp(...);
}
- 步驟2:開始使用
class RScanCameraDialog extends StatefulWidget {
@override
_RScanCameraDialogState createState() => _RScanCameraDialogState();
}
class _RScanCameraDialogState extends State<RScanCameraDialog> {
RScanCameraController _controller;
bool isFirst = true;
@override
void initState() {
super.initState();
//判斷當(dāng)前是否有可用相機(jī)
if (rScanCameras != null && rScanCameras.length > 0) {
//初始化相機(jī)控制器,一般rScanCameras[0]為后置,rScanCameras[1]為前置攝像頭
_controller = RScanCameraController(
rScanCameras[0], RScanCameraResolutionPreset.max)
..addListener(() {
//監(jiān)聽掃碼返回結(jié)果
final result = _controller.result;
if (result != null) {
if (isFirst) {
//如果掃描到二維碼將結(jié)果返回到上一頁
Navigator.of(context).pop(result);
isFirst = false;
}
}
})
..initialize().then((_) {
//初始化相機(jī)
if (!mounted) {
return;
}
setState(() {});
});
}
}
@override
void dispose() {
_controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
//判斷是否有可用相機(jī)
if (rScanCameras == null || rScanCameras.length == 0) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: Text('not have available camera'),
),
);
}
//判斷相機(jī)如果沒有初始化,給它一個加載頁面
if (!_controller.value.isInitialized) {
return Container();
}
//獲取到相機(jī)
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: <Widget>[
ScanImageView(
child: AspectRatio(
//拿到相機(jī)的aspectRatio
aspectRatio: _controller.value.aspectRatio,
child: RScanCamera(_controller),
),
),
//閃光燈
Align(
alignment: Alignment.bottomCenter,
child: FutureBuilder(
future: getFlashMode(),
builder: _buildFlashBtn,
))
],
),
);
}
//獲取閃光燈是否打開
Future<bool> getFlashMode() async {
bool isOpen = false;
try {
isOpen = await _controller.getFlashMode();
} catch (_) {}
return isOpen;
}
//構(gòu)建閃光燈按鈕
Widget _buildFlashBtn(BuildContext context, AsyncSnapshot<bool> snapshot) {
return snapshot.hasData
? Padding(
padding: EdgeInsets.only(bottom:24+MediaQuery.of(context).padding.bottom),
child: IconButton(
icon: Icon(snapshot.data ? Icons.flash_on : Icons.flash_off),
color: Colors.white,
iconSize: 46,
onPressed: () {
if (snapshot.data) {
_controller.setFlashMode(false);
} else {
_controller.setFlashMode(true);
}
setState(() {});
}),
)
: Container();
}
}
5.(已棄用)基于PlatformView使用相機(jī)掃描二維碼/條形碼
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:r_scan/r_scan.dart';
class RScanDialog extends StatefulWidget {
@override
_RScanDialogState createState() => _RScanDialogState();
}
class _RScanDialogState extends State<RScanDialog> {
RScanController _controller;
@override
void initState() {
super.initState();
initController();
}
bool isFirst=true;
Future<void> initController() async {
_controller = RScanController();
_controller.addListener(() {//監(jiān)聽掃描到的二維碼
final result = _controller.result;
if (result != null) {
if(isFirst){
Navigator.of(context).pop(result);
isFirst=false;
}
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
body: FutureBuilder<bool>(
future: canOpenCameraView(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (snapshot.hasData && snapshot.data == true) {
return ScanImageView(//這個為自己寫的前景
child: RScanView(
controller: _controller,
),
);
} else {
return Container();
}
},
),
),
);
}
Future<bool> canOpenCameraView() async {
var status =
await PermissionHandler().checkPermissionStatus(PermissionGroup.camera);
if (status != PermissionStatus.granted) {
var future = await PermissionHandler()
.requestPermissions([PermissionGroup.camera]);
for (final item in future.entries) {
if (item.value != PermissionStatus.granted) {
return false;
}
}
} else {
return true;
}
return true;
}
}
6. 打開閃光燈/獲取閃光燈狀態(tài)
使用RScanController類的實例直接調(diào)用
//關(guān)閉閃光燈
await _controller.setFlashMode(false);
//打開閃光燈
await _controller.setFlashMode(true);
// 獲取閃光燈狀態(tài)
bool isOpen = await _controller.getFlashMode();
7.RScanResult(二維碼掃描結(jié)果)
當(dāng)掃描到二維碼&條形碼將返回該對象,包含如下內(nèi)容
class RScanResult {
/// 條形碼類型
final RScanBarType type;
///附帶的信息
final String message;
///條形碼對應(yīng)的區(qū)域 包含 [x , y] 坐標(biāo)
final List<RScanPoint> points;
}
后續(xù)開發(fā)
- 支持自定義區(qū)域觸發(fā)掃描
- 還有更多...