123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- library fqreader;
- import 'dart:async';
- import 'dart:io';
- import 'dart:typed_data';
- import 'dart:ui' as ui;
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- typedef ScanEvent = Future<bool> Function(String value);
- class Fqreader {
- static const MethodChannel _channel =
- const MethodChannel('fqreader');
- static Future<String> decodeImg(File file,List<ScanType> scanType) async{
- var scanStr = new List<String>();
- scanType.forEach((item){
- scanStr.add(item.toString());
- });
- List<int> data = file.readAsBytesSync();
- Uint8List uData = new Uint8List.fromList(data);
- return await _channel.invokeMethod('decodeImg',{
- "image": uData,
- "scanType": scanStr
- });
- }
- static Future<int> _initView({
- @required Rect viewRect,
- @required Rect scanRect,
- @required List<ScanType> scanType,
- double devicePixelRatio
- }) async {
- var scanStr = new List<String>();
- scanType.forEach((item){
- scanStr.add(item.toString());
- });
- final int textureId = await _channel.invokeMethod('initView',{
- "viewRect":{
- "left":(viewRect.left * devicePixelRatio).toInt(),
- "top":(viewRect.top* devicePixelRatio).toInt(),
- "right":(viewRect.right* devicePixelRatio).toInt(),
- "bottom":(viewRect.bottom* devicePixelRatio).toInt()
- },
- "scanRect":{
- "left":(scanRect.left* devicePixelRatio).toInt(),
- "top":(scanRect.top* devicePixelRatio).toInt(),
- "right":(scanRect.right* devicePixelRatio).toInt(),
- "bottom":(scanRect.bottom* devicePixelRatio).toInt(),
- },
- "scanType": scanStr
- });
- return textureId;
- }
- static Future _startScan() async{
- await _channel.invokeMethod('startScan');
- }
- static Future _stopScan() async{
- await _channel.invokeMethod('stopScan');
- }
- static Future _turnOn() async{
- await _channel.invokeMethod("turnOn");
- }
- static Future _turnOff() async{
- await _channel.invokeMethod("turnOff");
- }
- static Future _release() async{
- await _channel.invokeMethod("release");
- }
- }
- class ScanView extends StatefulWidget{
- /**
- * 扫描事件
- */
- final ScanEvent onScan;
- /**
- * 扫描区域大小
- */
- final Rect scanRect;
- /**
- * ScanView控件大小
- */
- final Rect viewRect;
- /**
- * 是否立即扫描
- */
- final bool autoScan;
- /**
- * 是否连续扫描
- */
- final bool continuityScan;
- /**
- * 连续扫描间隔
- */
- final Duration scanInterval;
- /**
- * 扫描的条码类型
- */
- final List<ScanType> scanType;
- const ScanView({
- Key key,
- this.onScan,
- @required this.viewRect,
- @required this.scanRect,
- this.scanType = const [ScanType.ALL],
- this.autoScan = true,
- this.continuityScan = false,
- this.scanInterval = const Duration(milliseconds:500)})
- : super(key:key);
- @override
- State<StatefulWidget> createState() =>ScanViewState();
- }
- class ScanViewState extends State<ScanView>{
- int _textureId;
- StreamSubscription _readySubscription;
- @override
- void initState() {
- // TODO: implement initState
- super.initState();
- MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
- Fqreader._initView(
- viewRect: widget.viewRect,
- scanRect:widget.scanRect,
- devicePixelRatio:mediaQuery.devicePixelRatio,
- scanType: widget.scanType
- ).then((textureId){
- setState(() {
- _textureId = textureId;
- });
- if(widget.autoScan){
- Fqreader._startScan();
- }
- _readySubscription = new EventChannel('fqreader/scanEvents$_textureId')
- .receiveBroadcastStream()
- .listen(_listener);
- });
- }
- @override
- Widget build(BuildContext context) {
- return _textureId != null
- ? new Texture(textureId: _textureId)
- : new Container();
- }
- @override
- void dispose(){
- super.dispose();
- _readySubscription.cancel();
- Fqreader._release();
- }
- /**
- * 开始扫描
- */
- Future startScan() async{
- await Fqreader._startScan();
- }
- /**
- * 暂停扫描
- */
- Future stopScan() async{
- await Fqreader._stopScan();
- }
- /**
- * 开灯
- */
- Future turnOn() async{
- await Fqreader._turnOn();
- }
- /**
- * 关灯
- */
- Future turnOff() async{
- await Fqreader._turnOff();
- }
- void _listener(dynamic value) {
- if(widget != null)
- {
- if(!widget.continuityScan) //是否连续扫描
- {
- Fqreader._stopScan();
- }
- widget.onScan(value).then((result){
- if(widget.continuityScan && result){
- Future.delayed(widget.scanInterval,(){
- Fqreader._startScan();
- });
- }else{
- Fqreader._stopScan();
- }
- });
- }
- }
- }
- enum ScanType{
- /**
- * 所有条形码
- */
- ALL,
- /**
- * 普通二维码
- */
- QR_CODE,
- /**
- * 二维码 主要用于航空。比如坐飞机行李箱上贴的便签
- */
- AZTEC,
- /**
- * 条形码
- */
- CODABAR,
- /**
- * CODE 39 条形码
- */
- CODE_39,
- /**
- * CODE 92 条形码
- */
- CODE_93,
- /**
- * CODE 128 条形码
- */
- CODE_128,
- /**
- * 商品用条形码 EAN8
- */
- EAN8,
- /**
- * 商品用条形码 EAN13
- */
- EAN13,
- /**
- * 全球贸易货号。主要用于运输方面的条形码
- */
- ITF,
- /**
- * 一种二维码
- */
- DATA_MATRIX,
- /**
- * PDF417条码是一种高密度、高信息含量的便携式数据文件
- */
- PDF_417
- }
|