|
- import 'dart:async';
-
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
-
- typedef QRViewCreatedCallback = void Function(QRViewController);
-
- enum BarcodeFormat {
- /// Aztec 2D barcode format.
- aztec,
-
- /// CODABAR 1D format.
- codabar,
-
- /// Code 39 1D format.
- code39,
-
- /// Code 93 1D format.
- code93,
-
- /// Code 128 1D format.
- code128,
-
- /// Data Matrix 2D barcode format.
- dataMatrix,
-
- /// EAN-8 1D format.
- ean8,
-
- /// EAN-13 1D format.
- ean13,
-
- /// ITF (Interleaved Two of Five) 1D format.
- itf,
-
- /// MaxiCode 2D barcode format.
- maxicode,
-
- /// PDF417 format.
- pdf417,
-
- /// QR Code 2D barcode format.
- qrcode,
-
- /// RSS 14
- rss14,
-
- /// RSS EXPANDED
- rssExpanded,
-
- /// UPC-A 1D format.
- upcA,
-
- /// UPC-E 1D format.
- upcE,
-
- /// UPC/EAN extension format. Not a stand-alone format.
- upcEanExtension
- }
-
- const _formatNames = <String, BarcodeFormat>{
- 'AZTEC': BarcodeFormat.aztec,
- 'CODABAR': BarcodeFormat.codabar,
- 'CODE_39': BarcodeFormat.code39,
- 'CODE_93': BarcodeFormat.code93,
- 'CODE_128': BarcodeFormat.code128,
- 'DATA_MATRIX': BarcodeFormat.dataMatrix,
- 'EAN_8': BarcodeFormat.ean8,
- 'EAN_13': BarcodeFormat.ean13,
- 'ITF': BarcodeFormat.itf,
- 'MAXICODE': BarcodeFormat.maxicode,
- 'PDF_417': BarcodeFormat.pdf417,
- 'QR_CODE': BarcodeFormat.qrcode,
- 'RSS_14': BarcodeFormat.rss14,
- 'RSS_EXPANDED': BarcodeFormat.rssExpanded,
- 'UPC_A': BarcodeFormat.upcA,
- 'UPC_E': BarcodeFormat.upcE,
- 'UPC_EAN_EXTENSION': BarcodeFormat.upcEanExtension,
- };
-
- class Barcode {
- Barcode(this.code, this.format);
-
- final String code;
- final BarcodeFormat format;
- }
-
- class QRView extends StatefulWidget {
- const QRView({
- @required Key key,
- @required this.onQRViewCreated,
- this.overlay,
- }) : assert(key != null),
- assert(onQRViewCreated != null),
- super(key: key);
-
- final QRViewCreatedCallback onQRViewCreated;
-
- final ShapeBorder overlay;
-
- @override
- State<StatefulWidget> createState() => _QRViewState();
- }
-
- class _QRViewState extends State<QRView> {
- @override
- Widget build(BuildContext context) {
- return Stack(
- children: [
- _getPlatformQrView(),
- if (widget.overlay != null)
- Container(
- decoration: ShapeDecoration(
- shape: widget.overlay,
- ),
- )
- else
- Container(),
- ],
- );
- }
-
- Widget _getPlatformQrView() {
- Widget _platformQrView;
- switch (defaultTargetPlatform) {
- case TargetPlatform.android:
- _platformQrView = AndroidView(
- viewType: 'net.touchcapture.qr.flutterqr/qrview',
- onPlatformViewCreated: _onPlatformViewCreated,
- );
- break;
- case TargetPlatform.iOS:
- _platformQrView = UiKitView(
- viewType: 'net.touchcapture.qr.flutterqr/qrview',
- onPlatformViewCreated: _onPlatformViewCreated,
- creationParams: _CreationParams.fromWidget(0, 0).toMap(),
- creationParamsCodec: StandardMessageCodec(),
- );
- break;
- default:
- throw UnsupportedError(
- "Trying to use the default webview implementation for $defaultTargetPlatform but there isn't a default one");
- }
- return _platformQrView;
- }
-
- void _onPlatformViewCreated(int id) {
- if (widget.onQRViewCreated == null) {
- return;
- }
- widget.onQRViewCreated(QRViewController._(id, widget.key));
- }
- }
-
- class _CreationParams {
- _CreationParams({this.width, this.height});
-
- static _CreationParams fromWidget(double width, double height) {
- return _CreationParams(
- width: width,
- height: height,
- );
- }
-
- final double width;
- final double height;
-
- Map<String, dynamic> toMap() {
- return <String, dynamic>{
- 'width': width,
- 'height': height,
- };
- }
- }
-
- class QRViewController {
- QRViewController._(int id, GlobalKey qrKey)
- : _channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id') {
- if (defaultTargetPlatform == TargetPlatform.iOS) {
- final RenderBox renderBox = qrKey.currentContext.findRenderObject();
- _channel.invokeMethod('setDimensions',
- {'width': renderBox.size.width, 'height': renderBox.size.height});
- }
- _channel.setMethodCallHandler(
- (call) async {
- switch (call.method) {
- case scanMethodCall:
- if (call.arguments != null) {
- final args = call.arguments as Map;
- final code = args['code'] as String;
- final rawType = args['type'] as String;
- final format = _formatNames[rawType];
- if (format != null) {
- final barcode = Barcode(code, format);
- _scanUpdateController.sink.add(barcode);
- } else {
- throw Exception('Unexpected barcode type $rawType');
- }
- }
- }
- },
- );
- }
-
- static const scanMethodCall = 'onRecognizeQR';
-
- final MethodChannel _channel;
-
- final StreamController<Barcode> _scanUpdateController =
- StreamController<Barcode>();
-
- Stream<Barcode> get scannedDataStream => _scanUpdateController.stream;
-
- void flipCamera() {
- _channel.invokeMethod('flipCamera');
- }
-
- void toggleFlash() {
- _channel.invokeMethod('toggleFlash');
- }
-
- void pauseCamera() {
- _channel.invokeMethod('pauseCamera');
- }
-
- void resumeCamera() {
- _channel.invokeMethod('resumeCamera');
- }
-
- void dispose() {
- _scanUpdateController.close();
- }
- }
|