Flutter如何实现广播模式的条码扫码插件

Flutter如何实现一个支持广播模式的条码扫码插件?目前使用的扫码插件只能将结果返回给当前页面,但我们需要在多页面同时监听扫码结果。有没有成熟的方案或插件推荐?或者如何基于现有插件改造实现广播功能?

2 回复

使用Flutter实现广播模式的条码扫码插件,可借助flutter_barcode_listener库。步骤如下:

  1. 添加依赖到pubspec.yaml
  2. 在应用中监听扫码事件,通过BarcodeScanner接收广播数据。
  3. 处理扫码结果,支持多个监听器同时响应。

示例代码:

BarcodeScanner.listen((barcode) {
  print('扫描到: $barcode');
});

更多关于Flutter如何实现广播模式的条码扫码插件的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现广播模式的条码扫码插件,可以通过MethodChannel接收原生平台的扫码结果,并使用Stream进行广播。以下是核心实现步骤:

1. 插件基本结构

创建Flutter插件:

flutter create --template=plugin barcode_scanner

2. Dart端实现

// lib/barcode_scanner.dart
import 'dart:async';
import 'package:flutter/services.dart';

class BarcodeScanner {
  static const MethodChannel _channel = 
      MethodChannel('barcode_scanner');
  
  static final StreamController<String> _streamController = 
      StreamController.broadcast(); // 广播Stream
  
  static Stream<String> get onBarcodeScanned => _streamController.stream;
  
  static Future<void> startScan() async {
    try {
      await _channel.invokeMethod('startScan');
    } on PlatformException catch (e) {
      print("启动扫描失败: ${e.message}");
    }
  }
  
  // 供原生平台调用的结果接收方法
  static void receiveBarcodeResult(String barcode) {
    _streamController.add(barcode); // 广播结果
  }
}

3. Android端实现 (Kotlin)

// android/src/main/kotlin/BarcodeScannerPlugin.kt
class BarcodeScannerPlugin : MethodCallHandler {
  private var activity: Activity? = null
  
  companion object {
    @JvmStatic
    fun registerWith(registrar: Registrar) {
      val plugin = BarcodeScannerPlugin()
      plugin.activity = registrar.activity()
      val channel = MethodChannel(registrar.messenger(), "barcode_scanner")
      channel.setMethodCallHandler(plugin)
    }
  }
  
  override fun onMethodCall(call: MethodCall, result: Result) {
    when (call.method) {
      "startScan" -> {
        // 启动扫码Activity(如ZXing)
        val intent = Intent(activity, ScanActivity::class.java)
        activity?.startActivity(intent)
        result.success(null)
      }
      else -> result.notImplemented()
    }
  }
  
  // 在扫码结果返回时调用Flutter端
  fun sendBarcodeResult(barcode: String) {
    MethodChannel(flutterView, "barcode_scanner").invokeMethod(
      "receiveBarcodeResult", barcode)
  }
}

4. iOS端实现 (Swift)

// ios/Classes/BarcodeScannerPlugin.swift
public class SwiftBarcodeScannerPlugin: NSObject, FlutterPlugin {
  public static func register(with registrar: FlutterPluginRegistrar) {
    let channel = FlutterMethodChannel(
      name: "barcode_scanner",
      binaryMessenger: registrar.messenger())
    let instance = SwiftBarcodeScannerPlugin()
    registrar.addMethodCallDelegate(instance, channel: channel)
  }

  public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
    switch call.method {
    case "startScan":
      // 启动原生扫码控制器
      let scanner = ScannerViewController()
      scanner.completion = { barcode in
        // 回调结果到Flutter
        if let barcode = barcode {
          self.invokeFlutterMethod("receiveBarcodeResult", arguments: barcode)
        }
      }
      UIApplication.shared.keyWindow?.rootViewController?.present(scanner, animated: true)
      result(nil)
    default:
      result(FlutterMethodNotImplemented)
    }
  }
  
  private func invokeFlutterMethod(_ method: String, arguments: Any?) {
    // 通过MethodChannel回调到Dart端
    channel?.invokeMethod(method, arguments: arguments)
  }
}

5. 使用方式

// 在Flutter应用中
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // 监听广播
    BarcodeScanner.onBarcodeScanned.listen((barcode) {
      print("收到条码: $barcode");
      // 多个页面都会同时收到通知
    });
    
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: ElevatedButton(
            onPressed: BarcodeScanner.startScan,
            child: Text('开始扫码'),
          ),
        ),
      ),
    );
  }
}

关键点说明:

  1. 广播模式:使用StreamController.broadcast()创建广播流
  2. 跨平台通信:通过MethodChannel实现Dart与原生平台的双向通信
  3. 结果分发:原生平台将扫码结果通过MethodChannel回调到Dart端,再通过Stream广播
  4. 多监听器:任何监听onBarcodeScanned的Widget都会实时收到扫码结果

这种实现方式允许应用中的多个组件同时监听扫码结果,适合需要实时更新多个UI界面的场景。

回到顶部