I am developing a flutter app to read QR Codes. I am using qr_code_scanner: ^0.3.5
library. Below is my code.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class ScanQRCodeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Scan QR Code"),
),
body: _ScanQRCodeUI());
}
}
class _ScanQRCodeUI extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _ScanQRCodeUIState();
}
}
class _ScanQRCodeUIState extends State<_ScanQRCodeUI> {
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
Barcode result;
QRViewController controller;
// 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();
if (Platform.isAndroid) {
controller.pauseCamera();
} else if (Platform.isIOS) {
controller.resumeCamera();
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(flex: 4, child: _buildQrView(context)),
Expanded(flex: 1, child: _dataDisplayUI())
],
);
}
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)
? 200.0
: 400.0;
// To ensure the Scanner view is properly sizes after rotation
// we need to listen for Flutter SizeChanged notification and update controller
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: scanArea),
);
}
void _onQRViewCreated(QRViewController controller) {
setState(() {
this.controller = controller;
});
controller.scannedDataStream.listen((scanData) async {
print("Hello0");
setState(() {
result = scanData;
print(result.code);
});
// await controller.pauseCamera();
});
}
Widget _dataDisplayUI() {
const yellowColor = const Color(0xffEDE132);
return Column(
children: [
Row(
children: [
Expanded(
flex: 7,
child: Container(
margin:
EdgeInsets.only(top: 30, bottom: 30, left: 10, right: 10),
child:
Text("You have added 12 products. Click here to publish.",
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 14,
))),
)),
Expanded(
flex: 3,
child: Container(
width: 60,
height: 60,
child: Center(
child: Text("12",
style: GoogleFonts.poppins(
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 21,
)))),
decoration:
BoxDecoration(shape: BoxShape.circle, color: yellowColor),
))
],
)
],
);
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
}
I am using this app to scan products one by one, just like how the cashier does in a super marker using a barcode scanner.
The issue is, this scanner is listening to a stream
and it is keep on running. Pay your attention to the _onQRViewCreated
method. As a result, the same QR is being read multiple times before we even move the camera to the next QR code.
How can I make sure there is a delay between 2 scans? For an example, when I scan for a QR Code, I have to wait for another 2 seconds to scan the next QR.
If my idea of creating a delay between 2 scans is wrong, I am open for other ideas as well.
You can use
controller.scannedDataStream.first
that stops listening to other events from the stream.
Another solution would be to set an internal state property like below:
bool QrBeingProcessed = false;
and when you scan the first qr set it to true, till you're done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With