# Conflicts: # example/ios/Runner.xcodeproj/project.pbxprojflutter-beta
| @@ -3,6 +3,14 @@ | |||
| A QR code scanner that works on both iOS and Android by natively embedding the platform view within Flutter. The integration with Flutter is seamless, much better than jumping into a native Activity or a ViewController to perform the scan. | |||
| # *Warning* | |||
| If you are using Flutter Beta or Dev channel (1.25 or 1.26) you can get the following error: | |||
| `java.lang.AbstractMethodError: abstract method "void io.flutter.plugin.platform.PlatformView.onFlutterViewAttached(android.view.View)"` | |||
| This is a bug in Flutter which is being tracked here: https://github.com/flutter/flutter/issues/72185 | |||
| There is a workaround by adding `android.enableDexingArtifactTransform=false` to your `gradle.properties` file. | |||
| ## Screenshots | |||
| <table> | |||
| @@ -56,12 +64,16 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| Barcode result; | |||
| QRViewController controller; | |||
| /// Overriding reassemble and pausing the camera | |||
| /// ensures us that hot reload won't give a black screen | |||
| // In order to get hot reload to work we need to pause the camera if the platform | |||
| // is android, or resume the camera if the platform is iOS. | |||
| @override | |||
| void reassemble() { | |||
| super.reassemble(); | |||
| controller.pauseCamera(); | |||
| if (Platform.isAndroid) { | |||
| controller.pauseCamera(); | |||
| } else if (Platform.isIOS) { | |||
| controller.resumeCamera(); | |||
| } | |||
| } | |||
| @override | |||
| @@ -47,12 +47,16 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| QRViewController controller; | |||
| final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); | |||
| /// Overriding reassemble and pausing the camera | |||
| /// ensures us that hot reload won't give a black screen | |||
| // In order to get hot reload to work we need to pause the camera if the platform | |||
| // is android, or resume the camera if the platform is iOS. | |||
| @override | |||
| void reassemble() { | |||
| super.reassemble(); | |||
| controller.pauseCamera(); | |||
| if (Platform.isAndroid) { | |||
| controller.pauseCamera(); | |||
| } else if (Platform.isIOS) { | |||
| controller.resumeCamera(); | |||
| } | |||
| } | |||
| @override | |||
| @@ -69,7 +73,8 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, | |||
| children: <Widget>[ | |||
| if (result != null) | |||
| Text('Barcode Type: ${describeEnum(result.format)} Data: ${result.code}') | |||
| Text( | |||
| 'Barcode Type: ${describeEnum(result.format)} Data: ${result.code}') | |||
| else | |||
| Text('Scan a code'), | |||
| Row( | |||
| @@ -162,11 +167,17 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| } | |||
| Widget _buildQrView(BuildContext context) { | |||
| // For this example we check how width or tall the device is and change the scanArea and overlay accordingly. | |||
| var scanArea = (MediaQuery.of(context).size.width < 400 || | |||
| MediaQuery.of(context).size.height < 400) | |||
| ? 150.0 | |||
| : 300.0; | |||
| // To ensure the Scanner view is properly sizes after rotation | |||
| // we need to listen for Flutter SizeChanged notification and update controller | |||
| return NotificationListener<SizeChangedLayoutNotification>( | |||
| onNotification: (notification) { | |||
| Future.microtask(() => controller?.updateDimensions(qrKey)); | |||
| Future.microtask( | |||
| () => controller?.updateDimensions(qrKey, scanArea: scanArea)); | |||
| return false; | |||
| }, | |||
| child: SizeChangedLayoutNotifier( | |||
| @@ -179,7 +190,7 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| borderRadius: 10, | |||
| borderLength: 30, | |||
| borderWidth: 10, | |||
| cutOutSize: 300, | |||
| cutOutSize: scanArea, | |||
| ), | |||
| ))); | |||
| } | |||
| @@ -201,6 +212,7 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| } | |||
| ``` | |||
| @@ -148,7 +148,7 @@ class _QRViewExampleState extends State<QRViewExample> { | |||
| Widget _buildQrView(BuildContext context) { | |||
| // For this example we check how width or tall the device is and change the scanArea and overlay accordingly. | |||
| var scanArea = (MediaQuery.of(context).size.width < 500 || | |||
| var scanArea = (MediaQuery.of(context).size.width < 400 || | |||
| MediaQuery.of(context).size.height < 400) | |||
| ? 150.0 | |||
| : 300.0; | |||
| @@ -13,18 +13,15 @@ public class QRView:NSObject,FlutterPlatformView { | |||
| var scanner: MTBBarcodeScanner? | |||
| var registrar: FlutterPluginRegistrar | |||
| var channel: FlutterMethodChannel | |||
| var frame: CGRect | |||
| public init(withFrame frame: CGRect, withRegistrar registrar: FlutterPluginRegistrar, withId id: Int64){ | |||
| self.registrar = registrar | |||
| self.frame = frame | |||
| previewView = UIView(frame: frame) | |||
| channel = FlutterMethodChannel(name: "net.touchcapture.qr.flutterqr/qrview_\(id)", binaryMessenger: registrar.messenger()) | |||
| } | |||
| func isCameraAvailable(success: Bool) -> Void { | |||
| if success { | |||
| do { | |||
| try scanner?.startScanning(resultBlock: { [weak self] codes in | |||
| if let codes = codes { | |||
| @@ -56,7 +53,6 @@ public class QRView:NSObject,FlutterPlatformView { | |||
| default: | |||
| return | |||
| } | |||
| guard let stringValue = code.stringValue else { continue } | |||
| let result = ["code": stringValue, "type": typeString] | |||
| self?.channel.invokeMethod("onRecognizeQR", arguments: result) | |||