|  |  |  | import 'dart:async'; | 
					
						
							|  |  |  | import 'dart:io'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import 'package:nfc_manager/nfc_manager.dart'; | 
					
						
							|  |  |  | import 'package:nfc_manager/platform_tags.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void showNfcReader(BuildContext context, {required Function(String? nfcId) onNcfScan}) { | 
					
						
							|  |  |  |   showModalBottomSheet( | 
					
						
							|  |  |  |     context: context, | 
					
						
							|  |  |  |     enableDrag: false, | 
					
						
							|  |  |  |     isDismissible: false, | 
					
						
							|  |  |  |     shape: RoundedRectangleBorder( | 
					
						
							|  |  |  |       borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), | 
					
						
							|  |  |  |     ), | 
					
						
							|  |  |  |     backgroundColor: Colors.white, | 
					
						
							|  |  |  |     builder: (context) { | 
					
						
							|  |  |  |       return NfcLayout( | 
					
						
							|  |  |  |         onNcfScan: onNcfScan, | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class NfcLayout extends StatefulWidget { | 
					
						
							|  |  |  |   Function(String? nfcId) onNcfScan; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   NfcLayout({required this.onNcfScan}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   _NfcLayoutState createState() => _NfcLayoutState(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class _NfcLayoutState extends State<NfcLayout> { | 
					
						
							|  |  |  |   bool _reading = false; | 
					
						
							|  |  |  |   Widget? mainWidget; | 
					
						
							|  |  |  |   String? nfcId; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   void initState() { | 
					
						
							|  |  |  |     super.initState(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NfcManager.instance.startSession(onDiscovered: (NfcTag tag) async { | 
					
						
							|  |  |  |       var f; | 
					
						
							|  |  |  |       if (Platform.isAndroid) { | 
					
						
							|  |  |  |         f = MifareUltralight(tag: tag, identifier: tag.data["nfca"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         f = MifareUltralight(tag: tag, identifier: tag.data["mifare"]["identifier"], type: 2, maxTransceiveLength: 252, timeout: 22); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       String identifier = f.identifier.map((e) => e.toRadixString(16).padLeft(2, '0')).join(''); | 
					
						
							|  |  |  |       nfcId = identifier; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       setState(() { | 
					
						
							|  |  |  |         _reading = true; | 
					
						
							|  |  |  |         mainWidget = doneNfc(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       Future.delayed(const Duration(seconds: 1), () { | 
					
						
							|  |  |  |         NfcManager.instance.stopSession(); | 
					
						
							|  |  |  |         Navigator.pop(context); | 
					
						
							|  |  |  |         // if (Platform.isAndroid) {
 | 
					
						
							|  |  |  |         //   Navigator.pop(context);
 | 
					
						
							|  |  |  |         // } else {
 | 
					
						
							|  |  |  |         //   Navigator.pop(context);
 | 
					
						
							|  |  |  |         //   Navigator.pop(context);
 | 
					
						
							|  |  |  |         // }
 | 
					
						
							|  |  |  |         widget.onNcfScan(nfcId); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }).catchError((err) { | 
					
						
							|  |  |  |       print(err); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     (mainWidget == null && !_reading) ? mainWidget = scanNfc() : mainWidget = doneNfc(); | 
					
						
							|  |  |  |     return AnimatedSwitcher(duration: Duration(milliseconds: 500), child: mainWidget); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Widget scanNfc() { | 
					
						
							|  |  |  |     return Container( | 
					
						
							|  |  |  |       key: ValueKey(1), | 
					
						
							|  |  |  |       child: Column( | 
					
						
							|  |  |  |         mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |         children: <Widget>[ | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Text( | 
					
						
							|  |  |  |             "Ready To Scan", | 
					
						
							|  |  |  |             style: TextStyle( | 
					
						
							|  |  |  |               fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |               fontSize: 24, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Image.asset( | 
					
						
							|  |  |  |             "assets/icons/nfc/ic_nfc.png", | 
					
						
							|  |  |  |             height: MediaQuery.of(context).size.width / 3, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Text( | 
					
						
							|  |  |  |             "Approach an NFC Tag", | 
					
						
							|  |  |  |             style: TextStyle( | 
					
						
							|  |  |  |               fontSize: 18, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           ButtonTheme( | 
					
						
							|  |  |  |             minWidth: MediaQuery.of(context).size.width / 1.2, | 
					
						
							|  |  |  |             height: 45.0, | 
					
						
							|  |  |  |             buttonColor: Colors.grey[300], | 
					
						
							|  |  |  |             shape: RoundedRectangleBorder( | 
					
						
							|  |  |  |               borderRadius: BorderRadius.circular(6), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             child: TextButton( | 
					
						
							|  |  |  |               onPressed: () { | 
					
						
							|  |  |  |                 NfcManager.instance.stopSession(); | 
					
						
							|  |  |  |                 Navigator.pop(context); | 
					
						
							|  |  |  |               }, | 
					
						
							|  |  |  |               // elevation: 0,
 | 
					
						
							|  |  |  |               child: Text("CANCEL"), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Widget doneNfc() { | 
					
						
							|  |  |  |     return Container( | 
					
						
							|  |  |  |       key: ValueKey(2), | 
					
						
							|  |  |  |       child: Column( | 
					
						
							|  |  |  |         mainAxisSize: MainAxisSize.min, | 
					
						
							|  |  |  |         children: <Widget>[ | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Text( | 
					
						
							|  |  |  |             "Successfully Scanned", | 
					
						
							|  |  |  |             style: TextStyle( | 
					
						
							|  |  |  |               fontWeight: FontWeight.bold, | 
					
						
							|  |  |  |               fontSize: 24, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Image.asset( | 
					
						
							|  |  |  |             "assets/icons/nfc/ic_done.png", | 
					
						
							|  |  |  |             height: MediaQuery.of(context).size.width / 3, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           Text( | 
					
						
							|  |  |  |             "Approach an NFC Tag", | 
					
						
							|  |  |  |             style: TextStyle( | 
					
						
							|  |  |  |               fontSize: 18, | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           ButtonTheme( | 
					
						
							|  |  |  |             minWidth: MediaQuery.of(context).size.width / 1.2, | 
					
						
							|  |  |  |             height: 45.0, | 
					
						
							|  |  |  |             buttonColor: Colors.grey[300], | 
					
						
							|  |  |  |             shape: RoundedRectangleBorder( | 
					
						
							|  |  |  |               borderRadius: BorderRadius.circular(6), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |             child: TextButton( | 
					
						
							|  |  |  |               // onPressed: () {
 | 
					
						
							|  |  |  |               //   _stream?.cancel();
 | 
					
						
							|  |  |  |               //   widget.onNcfScan(nfcId);
 | 
					
						
							|  |  |  |               //   Navigator.pop(context);
 | 
					
						
							|  |  |  |               // },
 | 
					
						
							|  |  |  |               onPressed: null, | 
					
						
							|  |  |  |               // elevation: 0,
 | 
					
						
							|  |  |  |               child: Text("DONE"), | 
					
						
							|  |  |  |             ), | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |           SizedBox( | 
					
						
							|  |  |  |             height: 30, | 
					
						
							|  |  |  |           ), | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |       ), | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |