Flutter条码扫描插件famoco_scanner的使用
Flutter条码扫描插件famoco_scanner的使用
需求
- 最低版本为Android 10 (API 28)。
兼容设备
兼容以下设备:
- FX 325 (
FX325,1
) - FX 335 (
FX335,1
)
测试设备:
- FX 335 (
FX335,1
)
使用方法
步骤1
在你的 MainActivity
中继承 FamocoScanPhysicalButtonHandlerActivity
。如果你有更优的方法来处理物理按钮,可以忽略此步骤。
忽略此步骤也意味着 FamocoScanner.instance.scanPhysicalButton
将不会被调用。
步骤2
只需使用 FamocoScanner.instance
。例如:
FamocoScanner.instance.startScan();
要拦截条形码,你只需要在 StatefulWidget
中使用 decodedComplete
:
[@override](/user/override)
void initState() {
super.initState();
_onDecodedSubscription = FamocoScanner.instance.decodedComplete.listen(
(data) {
setState(() {
_lastBarcodeScanned = data.barcode;
});
});
}
[@override](/user/override)
void dispose() {
super.dispose();
_onDecodedSubscription.cancel();
}
当订阅到 decodedComplete
时,会自动调用 FamocoScanner.instance.enableScanner()
。同样地,当取消订阅时,会自动调用 disableScanner
。
ℹ️ 实现实例会根据设备的品牌自动选择。
示例
你可以查看示例应用。
这是一个与SDK文档中的应用相同的示例:[Demo app (v1.3, source code)]。
完整示例代码
以下是完整的示例代码:
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](/user/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](/user/override)
void dispose() {
super.dispose();
// 不要忘记这一步。
_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](/user/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](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: SafeArea(
child: Column(
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
children: [
Text(
'请扫描条形码',
style: Theme.of(context).textTheme.titleLarge,
),
Container(
margin: const EdgeInsets.all(16),
child: Text(
_lastBarcodeScanned ?? '未扫描条形码',
style: Theme.of(context).textTheme.bodyMedium,
),
),
TextField(
controller: _textEditingController,
),
_buildCheckbox(
'启用焦点填充编辑文本',
_fillEditTextOnFocus.value,
(value) {
setState(() {
_fillEditTextOnFocus.value = value ?? false;
});
},
),
_buildCheckbox(
'连续扫描物理按钮',
_continousScanPhysicalButton,
(value) {
setState(() {
_continousScanPhysicalButton = value ?? false;
});
},
),
_buildCheckbox(
'非停止扫描',
_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 ? '停止' : '扫描'),
),
),
Expanded(
child: TextButton(
onPressed: _clearButtonPressed,
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
foregroundColor:
MaterialStateProperty.all(Colors.white),
),
child: const Text('清除'),
),
),
],
),
],
),
),
),
);
}
}
更多关于Flutter条码扫描插件famoco_scanner的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter条码扫描插件famoco_scanner的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
famoco_scanner
是一个用于 Flutter 应用的条码扫描插件,它允许你在应用中集成条码扫描功能。以下是如何在 Flutter 项目中使用 famoco_scanner
插件的步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 famoco_scanner
插件的依赖。
dependencies:
flutter:
sdk: flutter
famoco_scanner: ^1.0.0 # 请使用最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 famoco_scanner
插件。
import 'package:famoco_scanner/famoco_scanner.dart';
3. 初始化扫描器
在使用扫描功能之前,你需要初始化扫描器。
FamocoScanner scanner = FamocoScanner();
4. 启动扫描
你可以通过调用 startScan
方法来启动扫描。这个方法会返回一个 Future
,你可以通过 await
来获取扫描结果。
String? barcode = await scanner.startScan();
if (barcode != null) {
print("Scanned barcode: $barcode");
} else {
print("Scan was cancelled or failed");
}
5. 处理扫描结果
扫描结果会以字符串的形式返回。你可以根据需要对扫描结果进行处理。
6. 释放资源
当不再需要扫描器时,应该释放资源。
scanner.dispose();
完整示例
以下是一个完整的示例,展示了如何在 Flutter 应用中使用 famoco_scanner
插件。
import 'package:flutter/material.dart';
import 'package:famoco_scanner/famoco_scanner.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: ScannerScreen(),
);
}
}
class ScannerScreen extends StatefulWidget {
[@override](/user/override)
_ScannerScreenState createState() => _ScannerScreenState();
}
class _ScannerScreenState extends State<ScannerScreen> {
final FamocoScanner scanner = FamocoScanner();
String scannedBarcode = '';
[@override](/user/override)
void dispose() {
scanner.dispose();
super.dispose();
}
Future<void> scanBarcode() async {
String? barcode = await scanner.startScan();
if (barcode != null) {
setState(() {
scannedBarcode = barcode;
});
} else {
setState(() {
scannedBarcode = 'Scan failed or cancelled';
});
}
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Barcode Scanner'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Scanned Barcode: $scannedBarcode'),
SizedBox(height: 20),
ElevatedButton(
onPressed: scanBarcode,
child: Text('Scan Barcode'),
),
],
),
),
);
}
}