Flutter plugin for scanning and generating QR codes using the ZXing library, supporting Android, iOS, and desktop platforms
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

195 lines
5.4 KiB

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<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@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<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
Uint8List? createdCodeBytes;
Code? result;
Codes? multiResult;
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;
});
}
}