import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_zxing/flutter_zxing.dart'; import 'widgets/debug_info_widget.dart'; import 'widgets/scan_from_gallery_widget.dart'; import 'widgets/scan_mode_dropdown.dart'; import 'widgets/scan_result_widget.dart'; import 'widgets/unsupported_platform_widget.dart'; void main() { zx.setLogEnabled(false); runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State createState() => _MyAppState(); } class _MyAppState extends State { @override Widget build(BuildContext context) { return const MaterialApp( title: 'Flutter Zxing Example', home: DemoPage(), ); } } class DemoPage extends StatefulWidget { const DemoPage({Key? key}) : super(key: key); @override State createState() => _DemoPageState(); } class _DemoPageState extends State { Uint8List? createdCodeBytes; Code? result; Codes? multiResult; // Currently code positions works incorrect on Android in Portrait mode bool isMultiScan = false; bool showDebugInfo = true; int successScans = 0; int failedScans = 0; @override Widget build(BuildContext context) { final isCameraSupported = defaultTargetPlatform == TargetPlatform.iOS || defaultTargetPlatform == TargetPlatform.android; return DefaultTabController( length: 2, child: Scaffold( appBar: AppBar( title: const TabBar( tabs: [ Tab(text: 'Scan Code'), Tab(text: 'Create Code'), ], ), ), body: TabBarView( physics: const NeverScrollableScrollPhysics(), children: [ if (kIsWeb) const UnsupportedPlatformWidget() else if (!isCameraSupported) const Center( child: Text('Camera not supported on this platform'), ) else if (result != null && result?.isValid == true) ScanResultWidget( result: result, onScanAgain: () => setState(() => result = null), ) else Stack( children: [ ReaderWidget( onScan: _onScanSuccess, onScanFailure: _onScanFailure, onMultiScan: _onMultiScanSuccess, onMultiScanFailure: _onMultiScanFailure, isMultiScan: isMultiScan, scanDelay: isMultiScan ? Duration.zero : const Duration(milliseconds: 500), tryInverted: true, ), ScanFromGalleryWidget( onScan: _onScanSuccess, onScanFailure: _onScanFailure, ), // Change single/multi scan mode dropdown button ScanModeDropdown( isMultiScan: isMultiScan, onChanged: (value) { setState(() { isMultiScan = value; }); }, ), if (showDebugInfo) DebugInfoWidget( successScans: successScans, failedScans: failedScans, error: isMultiScan ? multiResult?.error : result?.error, duration: isMultiScan ? multiResult?.duration ?? 0 : result?.duration ?? 0, onReset: _onReset, ), ], ), if (kIsWeb) const UnsupportedPlatformWidget() else ListView( children: [ WriterWidget( messages: const Messages( createButton: 'Create Code', ), onSuccess: (result, bytes) { setState(() { createdCodeBytes = bytes; }); }, onError: (error) { _showMessage(context, 'Error: $error'); }, ), if (createdCodeBytes != null) Image.memory(createdCodeBytes ?? Uint8List(0), height: 400), ], ), ], ), ), ); } _onScanSuccess(Code? code) { setState(() { successScans++; result = code; }); } _onScanFailure(Code? code) { setState(() { failedScans++; result = code; }); if (code?.error?.isNotEmpty == true) { _showMessage(context, 'Error: ${code?.error}'); } } _onMultiScanSuccess(Codes codes) { setState(() { successScans++; multiResult = codes; }); } _onMultiScanFailure(Codes result) { setState(() { failedScans++; multiResult = result; }); if (result.codes.isNotEmpty == true) { _showMessage(context, 'Error: ${result.codes.first.error}'); } } _showMessage(BuildContext context, String message) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message)), ); } _onReset() { setState(() { successScans = 0; failedScans = 0; }); } }