You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			203 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Dart
		
	
			
		
		
	
	
			203 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Dart
		
	
| 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 SizedBox(
 | |
|       width: MediaQuery.sizeOf(context).width,
 | |
|       child: Column(
 | |
|         key: ValueKey(1),
 | |
| 
 | |
|         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(
 | |
|       width: MediaQuery.sizeOf(context).width,
 | |
|       child: Column(
 | |
|         key: ValueKey(2),
 | |
|         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,
 | |
|           ),
 | |
|         ],
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| }
 |