qr_scanner.dart 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import 'package:flutter/material.dart';
  2. import 'package:mobile_scanner/mobile_scanner.dart';
  3. import '../../widgets/widgets.dart';
  4. class QRScanner extends StatefulWidget {
  5. final Function(QRInfo) onQRViewCreated;
  6. const QRScanner({Key? key, required this.onQRViewCreated}) : super(key: key);
  7. @override
  8. _QRScannerState createState() => _QRScannerState();
  9. }
  10. class _QRScannerState extends State<QRScanner> with WidgetsBindingObserver {
  11. late MobileScannerController controller;
  12. bool isHandlingQRcode = false;
  13. @override
  14. void initState() {
  15. super.initState();
  16. WidgetsBinding.instance.addObserver(this);
  17. controller = MobileScannerController();
  18. controller.barcodes.listen(_handleBarcode);
  19. controller.start();
  20. }
  21. @override
  22. void dispose() {
  23. WidgetsBinding.instance.removeObserver(this);
  24. controller.dispose();
  25. super.dispose();
  26. }
  27. @override
  28. void didChangeAppLifecycleState(AppLifecycleState state) {
  29. switch (state) {
  30. case AppLifecycleState.resumed:
  31. controller.start();
  32. break;
  33. case AppLifecycleState.inactive:
  34. case AppLifecycleState.paused:
  35. controller.stop();
  36. break;
  37. case AppLifecycleState.detached:
  38. controller.dispose();
  39. break;
  40. default:
  41. break;
  42. }
  43. }
  44. void _handleBarcode(BarcodeCapture capture) async {
  45. if (isHandlingQRcode) return;
  46. final String? code = capture.barcodes.first.rawValue;
  47. if (code != null) {
  48. isHandlingQRcode = true;
  49. controller.stop();
  50. final qrData = QRValidacion.validarQR(code);
  51. if (qrData['isValid'] == 'true') {
  52. final qrInfo = QRInfo(
  53. idEmpresa: qrData['idEmpresa']!,
  54. numeroUnidad: qrData['numeroUnidad']!,
  55. );
  56. widget.onQRViewCreated(qrInfo);
  57. } else {
  58. await _showInvalidQRDialog();
  59. controller.start();
  60. }
  61. isHandlingQRcode = false;
  62. }
  63. }
  64. Future<void> _showInvalidQRDialog() async {
  65. return alerta(
  66. context,
  67. etiqueta: "El código QR escaneado no es válido.",
  68. );
  69. }
  70. @override
  71. Widget build(BuildContext context) {
  72. return Scaffold(
  73. appBar: encabezado(titulo: "ESCANEA CÓDIGO QR"),
  74. body: Column(
  75. children: <Widget>[
  76. Expanded(
  77. flex: 5,
  78. child: Stack(
  79. children: [
  80. MobileScanner(
  81. controller: controller,
  82. onDetect: _handleBarcode,
  83. ),
  84. QRScannerOverlay(),
  85. ],
  86. ),
  87. ),
  88. ],
  89. ),
  90. );
  91. }
  92. }
  93. class QRScannerOverlay extends StatelessWidget {
  94. @override
  95. Widget build(BuildContext context) {
  96. return LayoutBuilder(
  97. builder: (context, constraints) {
  98. final cutOutSize = 300.0;
  99. final borderLength = 30.0;
  100. final borderWidth = 10.0;
  101. final borderRadius = 10.0;
  102. final borderColor = Colors.red;
  103. return Stack(
  104. children: [
  105. Positioned(
  106. top: (constraints.maxHeight - cutOutSize) / 2,
  107. left: (constraints.maxWidth - cutOutSize) / 2,
  108. child: Container(
  109. width: cutOutSize,
  110. height: cutOutSize,
  111. decoration: BoxDecoration(
  112. borderRadius: BorderRadius.circular(borderRadius),
  113. border: Border.all(
  114. color: borderColor,
  115. width: borderWidth,
  116. ),
  117. ),
  118. ),
  119. ),
  120. ],
  121. );
  122. },
  123. );
  124. }
  125. }