You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter组件内条码相机显示及扫描结果保存实现方案咨询

Flutter 持续条码扫描实现(账单录入场景)

一、推荐的条码扫描组件

  • mobile_scanner:Flutter官方维护的插件,支持实时持续扫描,性能稳定,兼容多种条码格式,适配iOS/Android,是账单录入这类持续扫描场景的首选。
  • barcode_scan2:老牌扫描插件,功能完善,但维护频率低于mobile_scanner,适合需要兼容旧版本项目的场景。
  • flutter_barcode_scanner:轻量易用,但默认是单次扫描逻辑,需额外配置才能实现持续扫描,适合简单需求场景。

二、持续扫描核心实现(以mobile_scanner为例)

1. 依赖与权限配置

在pubspec.yaml中添加依赖:

dependencies:
  mobile_scanner: ^5.0.0
  • Android:在android/app/src/main/AndroidManifest.xml中添加相机权限:
<uses-permission android:name="android.permission.CAMERA" />
  • iOS:在ios/Runner/Info.plist中添加相机权限描述:
<key>NSCameraUsageDescription</key>
<string>需要相机权限进行条码扫描</string>

2. 持续扫描代码实现

实现相机持续开启+扫描记录展示的页面,自动过滤重复扫描结果:

import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:shared_preferences/shared_preferences.dart';

class BarcodeScannerPage extends StatefulWidget {
  const BarcodeScannerPage({super.key});

  @override
  State<BarcodeScannerPage> createState() => _BarcodeScannerPageState();
}

class _BarcodeScannerPageState extends State<BarcodeScannerPage> {
  MobileScannerController controller = MobileScannerController();
  List<String> scannedCodes = [];
  String? lastScannedCode;
  final Duration debounceDuration = const Duration(seconds: 2);

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

  // 加载本地已保存的扫描记录
  Future<void> _loadSavedCodes() async {
    final prefs = await SharedPreferences.getInstance();
    setState(() {
      scannedCodes = prefs.getStringList('scanned_codes') ?? [];
    });
  }

  // 保存新扫描的条码到本地
  Future<void> _saveScannedCode(String code) async {
    if (code == lastScannedCode) return;
    setState(() {
      scannedCodes.add(code);
      lastScannedCode = code;
    });
    final prefs = await SharedPreferences.getInstance();
    await prefs.setStringList('scanned_codes', scannedCodes);

    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('已记录条码:$code')),
    );

    Future.delayed(debounceDuration, () {
      setState(() {
        lastScannedCode = null;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('账单条码录入')),
      body: Column(
        children: [
          // 相机预览区域
          Expanded(
            flex: 3,
            child: MobileScanner(
              controller: controller,
              onDetect: (capture) {
                final barcodes = capture.barcodes;
                for (final barcode in barcodes) {
                  final code = barcode.rawValue;
                  if (code != null) _saveScannedCode(code);
                }
              },
            ),
          ),
          // 扫描记录列表
          Expanded(
            flex: 2,
            child: ListView.builder(
              itemCount: scannedCodes.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(scannedCodes[index]),
                  trailing: IconButton(
                    icon: const Icon(Icons.delete),
                    onPressed: () => _deleteCode(index),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }

  // 删除单条扫描记录
  Future<void> _deleteCode(int index) async {
    setState(() {
      scannedCodes.removeAt(index);
    });
    final prefs = await SharedPreferences.getInstance();
    await prefs.setStringList('scanned_codes', scannedCodes);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

三、扫描结果保存方案

1. 轻量本地存储:SharedPreferences

适合存储少量扫描记录,操作简单,快速实现基础需求,如示例所示。

2. 本地数据库:SQLite(推荐大量记录场景)

如果需要存储条码关联的额外信息(如扫描时间、账单备注),可使用sqflite插件建立数据表管理记录。

3. 云端存储:Firebase Firestore/后端API

需要多设备同步或后台管理时,可将扫描结果上传至云端数据库或后端接口。

关键注意事项

  • 防抖处理:必须添加防抖逻辑,避免同一条码被重复记录。
  • 权限处理:首次启动需申请相机权限,可配合permission_handler插件完成权限申请流程。
  • 资源释放:页面销毁时及时释放相机控制器,避免资源泄漏。

内容的提问来源于stack exchange,提问作者Yous y

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:25:23