I am trying to use Qr code scanner to extract information of the user for example user's picture, display name etc, by scanning a Qrcode with an endpoint as the message and passing the data data to a bottom modal. so, after the Qrcode is scanned and data is extracted, it should bring out the bottom modal with the details. it worked when I inputted the endpoint url, but the scanner kept on returning a result multiple times causing the modal to show multiple times, I want a situation where each time I scan the modal shows once.
scanner page
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
import 'package:scanner_test/get_profile.dart';
import 'package:scanner_test/responsive.dart';
class QrScanner extends StatefulWidget {
static const String pageName = '/qrScannnerPage';
const QrScanner({Key? key}) : super(key: key);
@override
State<QrScanner> createState() => _QrScannerState();
}
class _QrScannerState extends State<QrScanner> {
final qrKey = GlobalKey(debugLabel: 'QR');
Barcode? result;
QRViewController? controller;
Responsive responsive = Responsive();
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
GetProfile? profile;
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
void reassemble() {
super.reassemble();
if (Platform.isAndroid) {
controller!.pauseCamera();
} else if (Platform.isIOS) {
controller!.resumeCamera();
}
}
@override
void showInSnackBar(String value) {
_scaffoldKey.currentState!
.showSnackBar(new SnackBar(content: new Text(value)));
}
Future<GetProfile?> getProfileData(String url) async {
try {
// String token =
// Provider.of<TokenProvider>(context, listen: false).userToken;
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final item = json.decode(response.body);
print(response.body);
profile = GetProfile.fromJson(item);
showQrModal();
} else {
print("error");
}
} catch (e) {
log(e.toString());
}
return profile;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(responsive.heightMargin(context, 70)),
child: AppBar(
title: Text("Scan an xProfile",
style: TextStyle(
color: Color(0xff212121),
fontSize: responsive.heightMargin(context, 22),
fontWeight: FontWeight.w700)),
centerTitle: false,
backgroundColor: Colors.white,
//elevation: 50.0,
leading: IconButton(
color: Color(0xff212121),
icon: Icon(Icons.arrow_back),
tooltip: 'Menu Icon',
onPressed: () {
Navigator.pop(context);
},
),
),
),
body: Stack(
alignment: Alignment.center,
children: <Widget>[
buildQrView(context),
Positioned(
bottom: responsive.heightMargin(context, 92),
child: buildresult())
],
));
}
Widget buildresult() {
return //getProfileData("") != null
// ? showQrModal()
Text("Please hold the camera at the QRcode",
style: TextStyle(
color: Color(0xffffffff),
fontSize: responsive.heightMargin(context, 18),
fontWeight: FontWeight.w400));
}
Widget buildQrView(BuildContext context) {
return QRView(
key: qrKey,
onQRViewCreated: onQRViewCreated,
overlay: QrScannerOverlayShape(
borderColor: Color(0xff6FCF97),
borderRadius: responsive.heightMargin(context, 35),
borderLength: responsive.heightMargin(context, 70),
borderWidth: responsive.widthMargin(context, 10),
cutOutSize: responsive.widthMargin(context, 380),
),
);
}
showQrModal() {
return showModalBottomSheet<void>(
context: context,
backgroundColor: Colors.transparent,
builder: (BuildContext context) {
return Container(
height: responsive.heightMargin(context, 381),
width: responsive.widthMargin(context, 414),
margin: EdgeInsets.fromLTRB(
responsive.widthMargin(context, 7),
0,
responsive.widthMargin(context, 7),
responsive.heightMargin(context, 7)),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft:
Radius.circular(responsive.heightMargin(context, 40)),
topRight:
Radius.circular(responsive.heightMargin(context, 40)),
bottomLeft:
Radius.circular(responsive.heightMargin(context, 40)),
bottomRight: Radius.circular(
responsive.heightMargin(context, 40)))),
child: Column(children: [
SizedBox(
height: responsive.heightMargin(context, 17),
),
Container(
height: responsive.heightMargin(context, 4),
width: responsive.widthMargin(context, 64),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
responsive.heightMargin(context, 50)),
color: Color(0xff000000)),
),
SizedBox(height: responsive.heightMargin(context, 37)),
Text("QRcode Scan Successful",
style: TextStyle(
color: Color(0xff212121),
fontSize: responsive.heightMargin(context, 24),
fontWeight: FontWeight.w700)),
SizedBox(height: responsive.heightMargin(context, 15)),
Container(
height: responsive.heightMargin(context, 1),
width: responsive.widthMargin(context, 366),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
responsive.heightMargin(context, 50)),
color: Color(0xffEEEEEE)),
),
SizedBox(height: responsive.heightMargin(context, 24)),
Container(
height: responsive.heightMargin(context, 104),
width: responsive.widthMargin(context, 366),
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.grey.withOpacity(0.1),
spreadRadius: 1,
blurRadius: 2,
offset: Offset(
0.1,
0.1,
), // changes position of shadow
),
],
borderRadius: BorderRadius.circular(16),
color: Color(0xffffffff)),
//alignment: Alignment.center,
child: Padding(
padding: EdgeInsets.fromLTRB(
responsive.widthMargin(context, 20),
0,
responsive.widthMargin(context, 20),
0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Container(
height: responsive.heightMargin(context, 72),
width: responsive.widthMargin(context, 72),
child: CircleAvatar(
radius: responsive.heightMargin(context, 28),
backgroundColor: Colors.blueAccent,
backgroundImage: NetworkImage(
"${profile!.message!.profilePhoto}"),
),
),
SizedBox(width: responsive.heightMargin(context, 16)),
Container(
width: responsive.widthMargin(context, 150),
height: responsive.heightMargin(context, 48),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"${profile!.message!.firstName} ${profile!.message!.lastName}",
style: TextStyle(
color: Color(0xff212121),
fontSize: responsive.heightMargin(
context, 18),
fontWeight: FontWeight.w700)),
SizedBox(
height: responsive.heightMargin(context, 6),
),
Text("xProfile found!",
style: TextStyle(
color: Color(0xff616161),
fontSize: responsive.heightMargin(
context, 14),
fontWeight: FontWeight.w500)),
]),
),
SizedBox(width: responsive.heightMargin(context, 20)),
Container(
height: responsive.heightMargin(context, 24),
width: responsive.widthMargin(context, 68),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
responsive.heightMargin(context, 6)),
color: Color.fromRGBO(0, 135, 111, 1)),
child: Center(
child: Text(
"Basic User",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w600,
fontSize:
responsive.heightMargin(context, 10)),
),
),
),
],
),
),
),
SizedBox(
height: responsive.heightMargin(context, 24),
),
GestureDetector(
onTap: () {},
child: Container(
height: responsive.heightMargin(context, 58),
width: responsive.widthMargin(context, 380),
child: Center(
child: Text(
"Add to Connections",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.w700,
fontSize: responsive.heightMargin(context, 16)),
),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
responsive.heightMargin(context, 100)),
color: Color.fromRGBO(0, 135, 111, 1)),
),
)
]));
});
}
void onQRViewCreated(QRViewController controller) {
this.controller = controller;
controller.scannedDataStream.listen((scanData) {
setState(() {
getProfileData("${scanData.code}");
});
});
}
}
profile model
import 'dart:convert';
GetProfile getProfileFromJson(String str) =>
GetProfile.fromJson(json.decode(str));
String getProfileToJson(GetProfile data) => json.encode(data.toJson());
class GetProfile {
GetProfile({
this.status,
this.message,
});
String? status;
Message? message;
factory GetProfile.fromJson(Map<String, dynamic> json) => GetProfile(
status: json["status"],
message: Message.fromJson(json["message"]),
);
Map<String, dynamic> toJson() => {
"status": status,
"message": message?.toJson(),
};
}
class Message {
Message({
this.id,
this.firstName,
this.lastName,
this.email,
this.username,
this.createdAt,
this.updatedAt,
this.v,
this.password,
this.pin,
this.profilePhoto,
});
String? id;
String? firstName;
String? lastName;
String? email;
String? username;
DateTime? createdAt;
DateTime? updatedAt;
int? v;
String? password;
String? pin;
String? profilePhoto;
factory Message.fromJson(Map<String, dynamic> json) => Message(
id: json["_id"],
firstName: json["firstName"],
lastName: json["lastName"],
email: json["email"],
username: json["username"],
createdAt: DateTime.parse(json["createdAt"]),
updatedAt: DateTime.parse(json["updatedAt"]),
v: json["__v"],
password: json["password"],
pin: json["pin"],
profilePhoto: json["profilePhoto"],
);
Map<String, dynamic> toJson() => {
"_id": id,
"firstName": firstName,
"lastName": lastName,
"email": email,
"username": username,
"createdAt": createdAt?.toIso8601String(),
"updatedAt": updatedAt?.toIso8601String(),
"__v": v,
"password": password,
"pin": pin,
"profilePhoto": profilePhoto,
};
}