dart 带流Flutter块

xoshrz7s  于 2023-06-19  发布在  Flutter
关注(0)|答案(1)|浏览(140)

我想在我的应用程序中使用flutter block模式。它使用quick_blue库来扫描BLE设备。QuickBlue提供扫描结果流。我的目标是用一个事件开始扫描(每次发现设备时发出新状态),用另一个事件停止扫描。
问题:我不清楚如何取消活动的扫描事件。由于 * scanResultStream * 来自第三方库,我无法控制它。因此,emit.onEach保持活动状态,直到另一个 * StartScanEvent * 触发(感谢 * restartable()*)。
我看过flutter block与流example,但流是在应用程序内部创建的,所以用户可以完全控制它。我很感激你的建议。
这是我的区块代码:

class BLEBloc extends Bloc<BLEEvent, BLEState> {

final List<BlueScanResult> scanResult = [];
final Stream scanStream = QuickBlue.scanResultStream;

BLEBloc() : super(BLEInitState()) {
  on<StartScanEvent>((event, emit) async {
    QuickBlue.startScan();
    scanResult.clear();

    // want to cancel this 
    await emit.onEach(
      scanStream,
      onData: (data) {
        scanResult.add(data);
        emit(DeviceFoundState(scanResult));
      },
    );

    print("finished"); // finishes only on next StartScanEvent
  }, transformer: restartable());

  on<StopScanEvent>(
    (event, emit) {
      QuickBlue.stopScan();
      emit(ScanFinishedState());
    },
  );
}
}
kgsdhlau

kgsdhlau1#

我建议使用Stream.listen,这样你就可以随时取消订阅。

class BLEBloc extends Bloc<BLEEvent, BLEState> {
  final List<BlueScanResult> scanResult = [];
  final Stream scanStream = QuickBlue.scanResultStream;
  StreamSubscription? _sub;

  BLEBloc() : super(BLEInitState()) {
    on<StartScanEvent>((event, emit) async {
      QuickBlue.startScan();
      scanResult.clear();
      
      _sub = scanStream.listen((data) {
        scanResult.add(data);
        emit(DeviceFoundState(scanResult));
      });

    }, transformer: restartable());

    on<StopScanEvent>(
      (event, emit) {
        _sub?.cancel();
        QuickBlue.stopScan();
        emit(ScanFinishedState());
      },
    );
  }
}

相关问题