首页 > 解决方案 > 提供者从 ChangeNotifier 通知其他侦听器

问题描述

我有以下设置:

具有多个页面的应用程序:VoltagesPage&TemperaturesPage

我将通过蓝牙串行接收一些数据,如下所示:

bluetooth_data_provider.dart

import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/widgets.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';

class BluetoothDataProvider with ChangeNotifier {
  String _data = '';
  String get data => _data;
  String _messageBuffer = '';

  BluetoothConnection? _connection;

  connectAndListen(String address) {
    BluetoothConnection.toAddress(address).then((connection) {
      print('Connected to the device');
      _connection = connection;

      if (_connection == null) {
        return;
      }

      _connection!.input!.listen(_onDataReceived).onDone(() {});
    }).catchError((error) {
      print('Cannot connect, exception occured');
      print(error);
    });
  }

  void _onDataReceived(Uint8List data) {
    String dataStr = ascii.decode(data);
    _messageBuffer += dataStr;

    if (dataStr.contains('\n')) {
      print(_messageBuffer);
      _data = _messageBuffer.substring(0, _messageBuffer.length - 1);
      _messageBuffer = '';

      notifyListeners();
    }
  }
}

这将通知所有监听器,监听BluetoothDataProvider's 对其data字段的更改。

现在,TemperaturesPage对消息并不真正感兴趣,VoltagesPage反之亦然。我可以通过设备发送的前缀来确定谁应该接收消息。

电压消息可能如下所示:

V:+12.5

温度消息可能如下所示:

T:+45.6

现在,当我BluetoothDataProvider从两个页面中观看时,小部件必须决定是否接受该消息。但这可能会使小部件挂起,因为它仍然需要重建build被调用的小部件。

我真正想要的是这样的:

import 'dart:convert';
import 'dart:typed_data';

import 'package:flutter/widgets.dart';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';

class BluetoothDataProvider with ChangeNotifier {
  String _data = '';
  String get data => _data;
  String _messageBuffer = '';

  BluetoothConnection? _connection;

  connectAndListen(String address) {
    BluetoothConnection.toAddress(address).then((connection) {
      print('Connected to the device');
      _connection = connection;

      if (_connection == null) {
        return;
      }

      _connection!.input!.listen(_onDataReceived).onDone(() {});
    }).catchError((error) {
      print('Cannot connect, exception occured');
      print(error);
    });
  }

  void _onDataReceived(Uint8List data) {
    String dataStr = ascii.decode(data);
    _messageBuffer += dataStr;

    if (dataStr.contains('\n')) {
      print(_messageBuffer);
      _data = _messageBuffer.substring(0, _messageBuffer.length - 1);
      _messageBuffer = ''; 

      if(_data.startsWith("T:")) {
        // notify with a TemperatureProvider
      } else if (_data.startsWith("V:")){
        // notify with a VoltageProvider
      }
    }
  }
}

这样,每个页面都可以监听不同的 Provider,并且只接收他们真正感兴趣的数据。

这样的场景可能吗?

谢谢!

标签: flutterflutter-provider

解决方案


我认为您可以使用选择器。每个页面都可以收听他们只感兴趣的数据。


推荐阅读