Flutter: How to pause and restart a `Stream` listener?
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.
Comments
-
PeakGen over 1 year
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.