Reputation: 151
This is a widget, that have function that triggers each time we scan qr code.
import 'package:qr_code_scanner/qr_code_scanner.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Expanded(
flex: 4,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Colors.red,
borderRadius: 10,
borderLength: 30,
borderWidth: 10,
cutOutSize: 300,
),
),
),
In function I want to navigate to next screen.
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
});
}
Problem here is that that listen event trigger many times, is it possible to stop this function after first successfully scan data? I try with
controller.scannedDataStream.first;
But that return empty string and not triggers when real data are scanned.
I need to click 40 times to go back from Second Route to return to QR scanner widget. Thanks!
Upvotes: 7
Views: 9963
Reputation: 732
I've faced the same issue, With lot of trial and error, found the solution qrViewController.dispose()
. It's below.
onQRViewCreated: (QRViewController qrViewController) {
this.qrViewController = qrViewController;
qrViewController.scannedDataStream.listen((qrData) {
final String qrCode = qrData.code;
qrViewController.dispose();
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(
qrCode: '$qrCode',
))).then((value) => qrViewController.resumeCamera());
});
}
Upvotes: 1
Reputation: 111
If someone still has this problem, try this solution:) It works well for me!
onQRViewCreated: (QRViewController qrViewController) {
this.qrViewController = qrViewController;
qrViewController.scannedDataStream.listen((qrData) {
qrViewController.pauseCamera();
final String qrCode = qrData.code;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(
qrCode: '$qrCode',
))).then((value) => qrViewController.resumeCamera());
});
}
Upvotes: 7
Reputation: 81
for future reference i found pausing the camera works better :)
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
qrText = scanData;
SecondPageRoute();
});
}
SecondPageRoute() async {
controller?.pauseCamera();
var value = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return SecondPage(qrText);
})).then((value) => controller.resumeCamera());
}
Upvotes: 8
Reputation: 451
You can just add a sentinel
void _onQRViewCreated(QRViewController controller) {
this.controller = controller;
bool scanned = false;
controller.scannedDataStream.listen((scanData) {
if (!scanned) {
scanned = true;
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondRoute()),
);
}
});
}
Upvotes: 5