famoco_scanner 1.0.1 famoco_scanner: ^1.0.1 copied to clipboard
A flutter implementation of the Famoco scanner device.
import 'dart:async';
import 'package:famoco_scanner/famoco_decoded_result.dart';
import 'package:famoco_scanner/famoco_physical_button_result.dart';
import 'package:famoco_scanner/famoco_scanner.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final StreamSubscription<FamocoDecodedResult> _onDecodedSubscription;
late final StreamSubscription<FamocoPhysicalButtonResult>
_onPhysicalButtonSubscription;
final _textEditingController = TextEditingController();
String? _lastBarcodeScanned;
ValueNotifier<bool> _fillEditTextOnFocus = ValueNotifier(false);
bool _continousScanPhysicalButton = false;
bool _nonStopScan = false;
bool _scanning = false;
@override
void dispose() {
super.dispose();
// Do not forget this.
_onDecodedSubscription.cancel();
_onPhysicalButtonSubscription.cancel();
_textEditingController.dispose();
_fillEditTextOnFocus.removeListener(_fillEditTextOnFocusChanged);
}
void _fillEditTextOnFocusChanged() {
FamocoScanner.instance.setOptions(
onDecodedUseKeyboardEvents: _fillEditTextOnFocus.value,
);
}
void _scanButtonPressed() {
if (_scanning) {
_startScan();
} else {
_stopScan();
}
}
void _clearButtonPressed() {
_lastBarcodeScanned = null;
_fillEditTextOnFocus.value = false;
_nonStopScan = false;
_continousScanPhysicalButton = false;
_scanning = false;
_textEditingController.clear();
setState(() {});
}
Widget _buildCheckbox(
String text,
bool value,
ValueChanged<bool?>? onChanged,
) {
return Row(
children: [
Checkbox(value: value, onChanged: onChanged),
Expanded(
child: Text(text),
),
],
);
}
void _startScan() {
setState(() {
_scanning = true;
});
FamocoScanner.instance.startScan(isHandsFree: _nonStopScan);
}
void _stopScan() {
setState(() {
_scanning = false;
});
FamocoScanner.instance.stopScan();
}
@override
void initState() {
super.initState();
_onDecodedSubscription = FamocoScanner.instance.decodedComplete.listen(
(data) {
if (!_nonStopScan) {
_stopScan();
}
_lastBarcodeScanned = data.barcode;
setState(() {});
},
);
_onPhysicalButtonSubscription =
FamocoScanner.instance.scanPhysicalButton.listen((event) {
if (event.isKeyDown) {
if (!_continousScanPhysicalButton) {
_startScan();
}
} else {
if (_continousScanPhysicalButton && _scanning) {
_startScan();
} else {
_stopScan();
}
}
});
_fillEditTextOnFocus.addListener(_fillEditTextOnFocusChanged);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Text(
'Please scan a barcode',
style: Theme.of(context).textTheme.titleLarge,
),
Container(
margin: const EdgeInsets.all(16),
child: Text(
_lastBarcodeScanned ?? 'No barcode scanned',
style: Theme.of(context).textTheme.bodyMedium,
),
),
TextField(
controller: _textEditingController,
),
_buildCheckbox(
'Enable fill edit text on focus',
_fillEditTextOnFocus.value,
(value) {
setState(() {
_fillEditTextOnFocus.value = value ?? false;
});
},
),
_buildCheckbox(
'Continous scan physical button',
_continousScanPhysicalButton,
(value) {
setState(() {
_continousScanPhysicalButton = value ?? false;
});
},
),
_buildCheckbox(
'Non-stop scan',
_nonStopScan,
(value) {
setState(() {
_nonStopScan = value ?? false;
});
},
),
],
),
),
),
Row(
children: [
Expanded(
child: TextButton(
onPressed: _scanButtonPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
_scanning ? Colors.red : Colors.green,
),
foregroundColor:
MaterialStateProperty.all(Colors.white),
),
child: Text(_scanning ? 'Stop' : 'Scan'),
),
),
Expanded(
child: TextButton(
onPressed: _clearButtonPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor:
MaterialStateProperty.all(Colors.white),
),
child: const Text('Clear'),
),
),
],
),
],
),
),
),
);
}
}