From 4512a3d28bde07e1be38ae47e5e54c4de12900f6 Mon Sep 17 00:00:00 2001 From: Luis Thein Date: Fri, 19 Jul 2019 00:19:46 +0200 Subject: [PATCH] Added scanDataStream & simplified Widget creation - the QrViewController has a getter that returns a Stream of data that gets updated on every scan result - theres no need to init the QrViewController through a method, because the GlobalKey is generated inside the QrViewWidget - a dispose method was added to correctly dispose the stream --- example/lib/main.dart | 23 ++++++++++------------- lib/qr_code_scanner.dart | 32 +++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index cc85f8a..c050628 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; void main() => runApp(MaterialApp(home: QRViewExample())); @@ -19,7 +18,6 @@ class QRViewExample extends StatefulWidget { } class _QRViewExampleState extends State { - final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); var qrText = ""; var flashState = flash_on; var cameraState = front_camera; @@ -32,7 +30,6 @@ class _QRViewExampleState extends State { children: [ Expanded( child: QRView( - key: qrKey, onQRViewCreated: _onQRViewCreated, ), flex: 4, @@ -128,17 +125,17 @@ class _QRViewExampleState extends State { } void _onQRViewCreated(QRViewController controller) { - final channel = controller.channel; - controller.init(qrKey); this.controller = controller; - channel.setMethodCallHandler((MethodCall call) async { - switch (call.method) { - case "onRecognizeQR": - dynamic arguments = call.arguments; - setState(() { - qrText = arguments.toString(); - }); - } + controller.scannedData.listen((scanData) { + setState(() { + qrText = scanData; + }); }); } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } } diff --git a/lib/qr_code_scanner.dart b/lib/qr_code_scanner.dart index 2f1cde2..d944a80 100644 --- a/lib/qr_code_scanner.dart +++ b/lib/qr_code_scanner.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -17,6 +19,7 @@ class QRView extends StatefulWidget { } class _QRViewState extends State { + final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); @override Widget build(BuildContext context) { var androidView = AndroidView( @@ -45,7 +48,7 @@ class _QRViewState extends State { if (widget.onQRViewCreated == null) { return; } - widget.onQRViewCreated(new QRViewController._(id)); + widget.onQRViewCreated(QRViewController._(id, qrKey)); } } @@ -71,18 +74,33 @@ class _CreationParams { } class QRViewController { - QRViewController._(int id) - : channel = MethodChannel('net.touchcapture.qr.flutterqr/qrview_$id'); - final MethodChannel channel; + static const scanMethodCall = "onRecognizeQR"; + + StreamController _scanUpdateController = StreamController(); - void init(GlobalKey qrKey) { + Stream get scannedData => _scanUpdateController.stream; + + 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( + (MethodCall call) async { + switch (call.method) { + case scanMethodCall: + if (call.arguments != null) { + _scanUpdateController.sink.add(call.arguments.toString()); + } + } + }, + ); } + final MethodChannel channel; + void flipCamera() { channel.invokeMethod("flipCamera"); } @@ -98,4 +116,8 @@ class QRViewController { void resumeCamera() { channel.invokeMethod("resumeCamera"); } + + void dispose() { + _scanUpdateController.close(); + } }