Flutter二维码扫描监听插件code_scan_listener的使用

发布于 1周前 作者 phonegap100 来自 Flutter

Flutter二维码扫描监听插件code_scan_listener的使用

此库是flutter_barcode_listener的一个分支。

它利用了HardwareKeyboard API而不是RawKeyboard API。

监听任何硬件条码扫描器。

条形码扫描问题

如果您需要从某些硬件条码扫描器获取条形码,通常有几种方法可以实现:

  1. 实现一些文本输入控件(例如TextEdit),调用焦点并进行扫描。
  2. 监听某些特殊的系统事件(例如来自Android服务的意图)。
  3. 监听原始键盘事件。

第一种方法很简单,如果您只需要在文本控件获得焦点时捕获扫描的条形码,那么这种方法就足够了,您也不需要这个包。

然而,如果您需要在没有文本输入控件或没有焦点的情况下获取扫描的条形码,则只剩下两种其他选择。

监听特殊系统事件(例如来自Android服务的意图)总是与特定制造商或设备相关联,并且通常需要实现某种SDK。这意味着您的实现将只支持已实现的这些设备上的条码扫描。此外,这种方法并不是跨平台友好的。

第三种方法是简单地监听原始键盘事件,并判断哪些是条形码,哪些不是。这种方法的缺点是你需要判断哪些是实际的用户交互,哪些是条形码扫描。优点是它不需要针对每个制造商或设备进行实现,您几乎支持所有条形码扫描器,包括通过蓝牙或Wi-Fi连接的外部设备。并且它是跨平台友好的。

实现思路

所有硬件条码设备都有几个共同点:

  • 扫描条码时,它们作为键盘工作。
  • 所有的键盘事件在一个极短的时间内触发(每个字符之间的间隔小于100毫秒)。
  • 条码以特殊字符(通常是回车键)结束。

为了判断什么是真正的条码,什么是应该忽略的普通键盘事件,该包使用以下逻辑:

  1. 监听物理键盘的原始按键释放事件。
  2. 只过滤出“真实”的字符(ASCII码小于256,不包括特殊字符,除了回车)。
  3. 每次新键入时检查前一个键是否超过bufferDuration时间,如果是则清除内部缓冲区。
  4. 检查新键是否是回车键,如果是则调用onBarcodeScanned回调并清除缓冲区。
  5. 如果不是回车键,则将其附加到内部缓冲区。

基本上来说,如果收到一组按键非常快且以回车键结尾,则认为这是一个有效的条码。

示例代码

import 'package:code_scan_listener/code_scan_listener.dart';
import 'package:flutter/material.dart';
import 'package:visibility_detector/visibility_detector.dart';

import 'second_screen.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '条形码扫描演示',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(title: '条形码扫描演示'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String? _barcode;
  late bool visible;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        // 添加可见性检测器以处理仅当部件可见时的条形码值
        child: VisibilityDetector(
          onVisibilityChanged: (VisibilityInfo info) {
            visible = info.visibleFraction > 0;
          },
          key: const Key('visible-detector-key'),
          child: CodeScanListener(
            bufferDuration: const Duration(milliseconds: 200),
            onBarcodeScanned: (barcode) {
              if (!visible) return;
              debugPrint(barcode);
              setState(() {
                _barcode = barcode;
              });
            },
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(
                  _barcode == null ? '扫描条形码' : '条形码: $_barcode',
                  style: Theme.of(context).textTheme.headlineSmall,
                ),
                Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: ElevatedButton(
                    onPressed: () => Navigator.push(
                      context,
                      MaterialPageRoute(
                        builder: (BuildContext context) => const SecondScreen(),
                      ),
                    ),
                    child: const Center(child: Text('第二屏')),
                  ),
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

更多关于Flutter二维码扫描监听插件code_scan_listener的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter二维码扫描监听插件code_scan_listener的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用code_scan_listener插件来实现二维码扫描监听的代码示例。假设你已经在pubspec.yaml文件中添加了code_scan_listener依赖,并且已经运行了flutter pub get

1. 添加依赖

首先,确保你的pubspec.yaml文件中包含以下依赖:

dependencies:
  flutter:
    sdk: flutter
  code_scan_listener: ^最新版本号 # 替换为最新版本号

2. 导入插件

在你的主Dart文件(例如main.dart)中导入插件:

import 'package:flutter/material.dart';
import 'package:code_scan_listener/code_scan_listener.dart';

3. 使用插件进行二维码扫描监听

下面是一个简单的示例,展示如何使用code_scan_listener插件来监听二维码扫描事件:

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter QR Code Scan Listener Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ScanListenerScreen(),
    );
  }
}

class ScanListenerScreen extends StatefulWidget {
  @override
  _ScanListenerScreenState createState() => _ScanListenerScreenState();
}

class _ScanListenerScreenState extends State<ScanListenerScreen> {
  String _scanResult = 'No scan result yet.';

  @override
  void initState() {
    super.initState();
    initScanListener();
  }

  void initScanListener() {
    CodeScanListener().startListening((result) {
      // 当二维码被扫描时,会调用此回调函数,并传递扫描结果
      setState(() {
        _scanResult = result;
      });
    }).then((_) {
      // 监听停止后的回调
      print('Scan listener stopped.');
    }).catchError((error) {
      // 错误处理
      print('Error: $error');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('QR Code Scan Listener Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Scan Result:',
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 10),
            Text(
              _scanResult,
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 确保在组件销毁时停止监听
    CodeScanListener().stopListening();
    super.dispose();
  }
}

说明

  1. 导入插件:首先导入code_scan_listener插件。
  2. 初始化监听:在initState方法中调用CodeScanListener().startListening()来开始监听二维码扫描事件。
  3. 处理扫描结果:当二维码被扫描时,回调函数会被调用,并传递扫描结果。使用setState更新UI以显示扫描结果。
  4. 停止监听:在dispose方法中调用CodeScanListener().stopListening()来停止监听,以确保在组件销毁时释放资源。

请注意,这个示例假设code_scan_listener插件提供了一个startListeningstopListening方法,以及一个回调机制来处理扫描结果。具体实现可能会根据插件的实际API有所不同,因此请参考插件的官方文档以获取最新的API信息。如果插件的API与示例中的不同,请根据实际情况进行调整。

回到顶部