From e87346e5b31e443fe39890a6c36f1d817aeb7c11 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Mon, 9 Mar 2026 10:33:20 +0300 Subject: [PATCH] qr & barcode scanner improvement. --- android/gradle.properties | 3 +- lib/views/widgets/qr/asset_scan_qr.dart | 133 ++++++++++++++++-------- lib/views/widgets/qr/scan_qr.dart | 58 +++++++---- pubspec.yaml | 1 + 4 files changed, 127 insertions(+), 68 deletions(-) diff --git a/android/gradle.properties b/android/gradle.properties index 898e4d70..ea54c785 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,3 +1,4 @@ org.gradle.jvmargs=-Xmx4096m -XX:MaxMetaspaceSize=1024m android.useAndroidX=true -android.enableJetifier=true \ No newline at end of file +android.enableJetifier=true +dev.steenbakker.mobile_scanner.useUnbundled=true \ No newline at end of file diff --git a/lib/views/widgets/qr/asset_scan_qr.dart b/lib/views/widgets/qr/asset_scan_qr.dart index 1737b65e..bc001e95 100644 --- a/lib/views/widgets/qr/asset_scan_qr.dart +++ b/lib/views/widgets/qr/asset_scan_qr.dart @@ -1,7 +1,9 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:provider/provider.dart'; import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart'; import 'package:test_sa/extensions/context_extension.dart'; @@ -34,34 +36,38 @@ class AssetScanQr extends StatefulWidget { class _AssetScanQrState extends State { // Barcode result; - QRViewController? _controller; + // QRViewController? _controller; bool _scanDone = false; bool _scanning = false; final GlobalKey qrKey = GlobalKey(debugLabel: 'QR_scanner'); late AssetProvider _devicesProvider; - // 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. + MobileScannerController? controller; + @override - void reassemble() { - super.reassemble(); - if (Platform.isAndroid) { - _controller?.pauseCamera(); - } else if (Platform.isIOS) { - _controller?.resumeCamera(); - } + void initState() { + // TODO: implement initState + super.initState(); + controller = MobileScannerController( + detectionSpeed: DetectionSpeed.noDuplicates, + formats: [], + returnImage: false, + torchEnabled: false, + invertImage: false, + autoZoom: true, + ); } @override void dispose() { super.dispose(); - _controller?.dispose(); + controller?.dispose(); _devicesProvider.searchReset(); } _pickManually() async { - _controller?.pauseCamera(); - await Navigator.push(context, MaterialPageRoute(builder: (context) => SearchDevicePage(multiSelection: widget.multiSelection))).then((value) => _controller?.resumeCamera()); + controller?.pause(); + await Navigator.push(context, MaterialPageRoute(builder: (context) => SearchDevicePage(multiSelection: widget.multiSelection))).then((value) => controller?.stop()); } _getDevice(String result, {bool isQr = false}) async { @@ -82,46 +88,83 @@ class _AssetScanQrState extends State { children: [ Stack( children: [ - QRView( + MobileScanner( key: qrKey, - onQRViewCreated: (QRViewController controller) { - setState(() { - _controller = controller; - }); - controller.scannedDataStream.listen((scanData) async { - if (!_scanDone) { - _scanDone = true; - if (!widget.enablePickManually) { - if (scanData.code != null) { - Navigator.of(context).pop(Asset(assetNumber: scanData.code!)); - } else { - _scanDone = false; - } + tapToFocus: true, + controller: controller, + onDetect: (result) async { + String? scanData = result.barcodes.first.rawValue; + if (!_scanDone) { + _scanDone = true; + if (!widget.enablePickManually) { + if (scanData != null) { + Navigator.of(context).pop(Asset(assetNumber: scanData)); } else { - _controller?.pauseCamera(); - setState(() { - _scanning = true; - }); - final result = await _getDevice(scanData.code!, isQr: true); - setState(() { - _scanning = false; - }); - if (result.isNotEmpty) { - if (widget.multiSelection) { - Navigator.of(context).pop([result[0]]); - } else { - Navigator.of(context).pop(result[0]); - } + _scanDone = false; + } + } else { + setState(() { + _scanning = true; + }); + final result = await _getDevice(scanData!, isQr: true); + setState(() { + _scanning = false; + }); + if (result.isNotEmpty) { + if (widget.multiSelection) { + Navigator.of(context).pop([result[0]]); } else { - Utils.showToast("No Item Found. Try Again", toastGravity: ToastGravity.CENTER); - _controller?.resumeCamera(); - _scanDone = false; + Navigator.of(context).pop(result[0]); } + } else { + Utils.showToast("No Item Found. Try Again", toastGravity: ToastGravity.CENTER); + _scanDone = false; } } - }); + } }, ), + + // QRView( + // key: qrKey, + // onQRViewCreated: (QRViewController controller) { + // setState(() { + // _controller = controller; + // }); + // controller.scannedDataStream.listen((scanData) async { + // if (!_scanDone) { + // _scanDone = true; + // if (!widget.enablePickManually) { + // if (scanData.code != null) { + // Navigator.of(context).pop(Asset(assetNumber: scanData.code!)); + // } else { + // _scanDone = false; + // } + // } else { + // _controller?.pauseCamera(); + // setState(() { + // _scanning = true; + // }); + // final result = await _getDevice(scanData.code!, isQr: true); + // setState(() { + // _scanning = false; + // }); + // if (result.isNotEmpty) { + // if (widget.multiSelection) { + // Navigator.of(context).pop([result[0]]); + // } else { + // Navigator.of(context).pop(result[0]); + // } + // } else { + // Utils.showToast("No Item Found. Try Again", toastGravity: ToastGravity.CENTER); + // _controller?.resumeCamera(); + // _scanDone = false; + // } + // } + // } + // }); + // }, + // ), Center( child: 'scan'.toSvgAsset( height: 283.toScreenHeight.toInt(), diff --git a/lib/views/widgets/qr/scan_qr.dart b/lib/views/widgets/qr/scan_qr.dart index def01183..bbef7f70 100644 --- a/lib/views/widgets/qr/scan_qr.dart +++ b/lib/views/widgets/qr/scan_qr.dart @@ -1,6 +1,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart'; import '../buttons/app_icon_button.dart'; @@ -14,7 +15,10 @@ class ScanQr extends StatefulWidget { class _ScanQrState extends State { // Barcode result; - QRViewController? _controller; + // QRViewController? _controller; + + MobileScannerController? controller; + bool _scanDone = false; final GlobalKey qrKey = GlobalKey(debugLabel: 'QR_scanner'); @@ -22,19 +26,34 @@ class _ScanQrState extends State { // is android, or resume the camera if the platform is iOS. @override - void reassemble() { - super.reassemble(); - if (Platform.isAndroid) { - _controller?.pauseCamera(); - } else if (Platform.isIOS) { - _controller?.resumeCamera(); - } + void initState() { + // TODO: implement initState + super.initState(); + controller = MobileScannerController( + detectionSpeed: DetectionSpeed.noDuplicates, + formats: [], + returnImage: false, + torchEnabled: false, + invertImage: false, + autoZoom: true, + ); } + // + // @override + // void reassemble() { + // super.reassemble(); + // if (Platform.isAndroid) { + // controller?.pauseCamera(); + // } else if (Platform.isIOS) { + // _controller?.resumeCamera(); + // } + // } + @override void dispose() { super.dispose(); - _controller?.dispose(); + // _controller?.dispose(); } @override @@ -42,20 +61,15 @@ class _ScanQrState extends State { return Scaffold( body: Stack( children: [ - QRView( - key: qrKey, - onQRViewCreated: (QRViewController controller) { - setState(() { - _controller = controller; - }); - controller.scannedDataStream.listen((scanData) { - if (!_scanDone) { - _scanDone = true; - Navigator.of(context).pop(scanData.code); - } - }); + MobileScanner( + tapToFocus: true, + controller: controller, + onDetect: (result) { + if (!_scanDone) { + _scanDone = true; + Navigator.of(context).pop(result.barcodes.first.rawValue); + } }, - overlay: QrScannerOverlayShape(borderColor: Colors.red, borderRadius: 10, borderLength: 30, borderWidth: 10, cutOutSize: 280), ), SafeArea( child: Padding( diff --git a/pubspec.yaml b/pubspec.yaml index 6b5a77a0..27a6086b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,7 @@ dependencies: another_flushbar: ^1.12.32 pinput: ^6.0.2 audioplayers: ^6.6.0 + mobile_scanner: ^7.2.0 flare_flutter: git: