Flutter Bloc A在Bloc B中添加流,但是此流将不会通过StreamBuilder在UI中呈现 [英] Flutter Bloc A adds stream in Bloc B but this stream will not render in UI via StreamBuilder

查看:110
本文介绍了Flutter Bloc A在Bloc B中添加流,但是此流将不会通过StreamBuilder在UI中呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图转向一个新的flutter项目的块/提供者体系结构.我已经对问题进行了一段时间的故障排除,其中一个集团的流将通过StreamBuilder在UI上呈现,而另一个集团则不会.在我继续之前,我希望(并且需要)学习原因.

我有两个集团,第一个是ble_service.我可以从UI调用函数到此块(app.dart第60-72行),该函数连接到设备并通过StreamBuilder渲染特征在UI中返回的内容(第98行).只需从UI中的ble设备渲染返回的json有效负载即可.每秒频繁更新多次.

我的计划是要有一个解析器块(bleBeltNotifyParser_bloc),它将解析来自ble_service的传入json有效负载,然后从那里的UI进行流传输.在ble_service中,我将json有效负载传递给parserInputSink,这是来自Parser Bloc的流(ble_service第99行).在bleBeltNotifyParser.bloc中,我在第21行上监听它,并将其传递给计划分析它的aTest2().我在这里停留是因为我试图在UI上渲染此数据(app.dart第108行),但是无论将数据传递到parserInputController的其他组合如何,UI都只会渲染种子数据.我通过在第28行上打印来确认流正在获取数据.

我还确认,可以通过非常简单地通过按钮(第73和80行)将一些数据放入流中来从UI进入Parser bloc.按下这些按钮后,该数据将添加到流中,并且UI将按预期进行更新.

为什么StreamBuilder可用于blue_service而不是bleBeltNotifyParser_bloc?我还尝试在服务中创建流,然后在解析器中侦听它.他们也没有运气.

我的main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  /// Starting here, everything is used regardless of dependencies
  var blocProvider = BlocProvider(
    bleBeltNotifyParserBloc: BleBeltNotifyParserBloc(),
    bleService: BleService(),

  );
  
  runApp(
    AppStateContainer(
      blocProvider: blocProvider,
      child:  App(),
    ),
  );
}

我的AppState

import 'package:flutter/material.dart';
import 'package:flutterappbelt3/main.dart';
import 'package:flutterappbelt3/blocs/ble_service.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';

class AppStateContainer extends StatefulWidget {
  final Widget child;
  final BlocProvider blocProvider;
  const AppStateContainer({
    Key key,
    @required this.child,
    @required this.blocProvider,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => AppState();

  static AppState of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_AppStoreContainer) as _AppStoreContainer).appData;
  }
}

class AppState extends State<AppStateContainer> {
  BlocProvider get blocProvider => widget.blocProvider;

  @override
  Widget build(BuildContext context) {
    return _AppStoreContainer(
      appData: this,
      blocProvider: widget.blocProvider,
      child: widget.child,
    );
  }

  void dispose() {
    super.dispose();
  }

}

class _AppStoreContainer extends InheritedWidget {
  final AppState appData;
  final BlocProvider blocProvider;

  _AppStoreContainer({
    Key key,
    @required this.appData,
    @required child,
    @required this.blocProvider,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(_AppStoreContainer oldWidget) => oldWidget.appData != this.appData;
}

class BlocProvider {
  BleBeltNotifyParserBloc bleBeltNotifyParserBloc = BleBeltNotifyParserBloc();
  BleService bleService;

  BlocProvider({
    @required this.bleBeltNotifyParserBloc,
    @required this.bleService,

  });
}

我的app.dart

import 'package:flutter/material.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';
import 'blocs/app_state.dart';
import 'blocs/ble_service.dart';

class App extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Position App',
      theme: new ThemeData(
        primarySwatch: Colors.red,
      ),
      home: PositionApp(),
    );
  }
}

class PositionApp extends StatefulWidget {
  @override
  _PositionAppState createState() => _PositionAppState();
}

class _PositionAppState extends State<PositionApp> {

  BleService _service = BleService();
  BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  @override
  void initState() {
    super.initState();
     //_service.startScan();
    //_service.bleNotifyFromBelt.listen((String data) {_bloc.parserInputSink.add(data);});
  }

  @override
  Widget build(BuildContext context) {
    //SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
    BleService _bleServiceBloc = AppStateContainer.of(context).blocProvider.bleService;
    BleBeltNotifyParserBloc _bleBeltNotifyParserBloc = AppStateContainer.of(context).blocProvider.bleBeltNotifyParserBloc;
    return Scaffold(
      appBar: AppBar(
        title: Text("Position"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              child: Text("hello"),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.startScan();
              },
                child: Text("Scan & Connect"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.discoverServices();
              },
                child: Text("discover services"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.disconnectFromDevice();
              },
                child: Text("disconnect"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.addToParserController1();
              },
                child: Text("Parser One"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.addToParserController2();
              },
                child: Text("Parser Two"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.aTest();
              },
                child: Text("aTest"),
              ),
            ),
            Container(
                child: StreamBuilder(
                    initialData: "0",
                    stream: _bleServiceBloc.bleNotifyFromBelt,
                    builder: (BuildContext context, AsyncSnapshot snapshot) {
                      if(snapshot.data == null) return CircularProgressIndicator();
                      else return Text(
                        snapshot.data.toString(),
                        style: TextStyle(fontSize: 14.0, color: Colors.black),
                        textAlign: TextAlign.center,
                      );}
                ),
              ),
            Container(
              child: StreamBuilder(
                  initialData: "0",
                  stream: _bleServiceBloc.bleStatusFromBelt,
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if(snapshot.data == null) return CircularProgressIndicator();
                    else return Text(
                      snapshot.data.toString(),
                      style: TextStyle(fontSize: 14.0, color: Colors.black),
                      textAlign: TextAlign.center,
                    );}
              ),
            ),
          ],
        ),
      ),
    );
  }
}

我的ble_service.dart


import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'dart:convert' show utf8;
import 'package:rxdart/rxdart.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';

class BleService {

//BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  final String TARGET_DEVICE_NAME = "ESP32";
  final String SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b";
  final String NOTIFY_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8";
  final String WRITE_UUID = "724b0547-3747-4c00-9710-5305a020018f";
  FlutterBlue flutterBlue = FlutterBlue.instance;
  StreamSubscription<ScanResult> scanSubScription;
  BluetoothDevice beltDevice;
  BluetoothCharacteristic characteristicNotify;
  BluetoothCharacteristic characteristicWrite;
  String bleNotifyString = "";

  BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  BehaviorSubject<String> _bleStatusFromBeltController = BehaviorSubject<String>.seeded("BLE STATUS");
  Stream<String> get bleStatusFromBelt => _bleStatusFromBeltController.stream;

  StreamController<String> _bleNotifyFromBeltController = BehaviorSubject<String>.seeded("BLE NOTIFY");
  Stream<String> get bleNotifyFromBelt => _bleNotifyFromBeltController.stream;
  Sink<String> get bleNotifyFromBeltSink => _bleNotifyFromBeltController.sink;

  BleService();

  dispose() {
    _bleStatusFromBeltController.close();
    _bleNotifyFromBeltController.close();
  }

  startScan() {
    //stopScan();
//    // SCANNING
    scanSubScription = flutterBlue.scan().listen((scanResult) async {
      if (scanResult.device.name == TARGET_DEVICE_NAME) {
        stopScan();
//        // FOUND
        beltDevice = await Future.value(scanResult.device).timeout(const Duration(seconds: 3));
        connectToDevice();
      }
    }, onDone: () => stopScan());
  }

  stopScan() {
    flutterBlue.stopScan();
    scanSubScription?.cancel();
    scanSubScription = null;
    _bleStatusFromBeltController.add("Disconnected");
    print("print Disconnected");
  }

  connectToDevice() async {
    if (beltDevice == null) return;
    // CONNECTING
    await beltDevice.connect();
    beltDevice.requestMtu(185);
    print('print DEVICE CONNECTED');
    print(" print BeltDevice $beltDevice");
    _bleStatusFromBeltController.add("Connected");
    print("print Connected");
    //discoverServices();
  }

  discoverServices() async {
    print("discoverServices beltDevice name is  $beltDevice");
    if (beltDevice == null) return;
    List<BluetoothService> services = await beltDevice.discoverServices();
    services.forEach((service) {
      // do something with service
      if (service.uuid.toString() == SERVICE_UUID) {
        service.characteristics.forEach((characteristic) {
          // set up notify characteristic
          print("Service Found for $characteristic");
          if (characteristic.uuid.toString() == NOTIFY_UUID) {
            characteristicNotify = characteristic;
            // tell characteristic on server to notify
            characteristicNotify.setNotifyValue(true);
            print("notify set to true");
            // listen, convert and put notify value in stream
            characteristicNotify.value.listen((value) {
              bleNotifyString = utf8.decode(value);
              //print("got characteristic $value");
              print(bleNotifyString);
              _bleNotifyFromBeltController.sink.add(bleNotifyString);
              _bloc.parserInputSink.add(bleNotifyString);
            });
            // COMMUNICATING
          }
          // Prepares characteristic for Write
          if (characteristic.uuid.toString() == WRITE_UUID) {
            characteristicWrite = characteristic;
          }
        });
      }
    });
  }
  disconnectFromDevice() {
    //if (beltDevice == null) return;
    //stopScan();
    beltDevice.disconnect();
    _bleStatusFromBeltController.add("Disconnect");
    print("Disconnect");
    // DISCONNECTED
  }
}

我的bleBeltNotifyParser_bloc 我无法渲染

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'dart:math' as Math;
import 'package:flutterappbelt3/blocs/ble_service.dart';


class BleBeltNotifyParserBloc{

 // final BleService _bloc = BleService();

  StreamController<String> _parserInputController = BehaviorSubject<String>.seeded("Parser Input");
  Stream<String> get parserInput => _parserInputController.stream;
  Sink<String> get parserInputSink => _parserInputController.sink;

  BleBeltNotifyParserBloc(){


    _parserInputController.stream.listen(_aTest2);

    //_bloc.bleNotifyFromBelt.listen((String data) {parserInputSink.add(data); print('Got eem! Input Parser $data');}); Tried various things - such as listening to streams originating from ble_service.


  }

  void _aTest2(data) {
    print("WHAT!!! $data");
  }

  void aTest() {
    //_bloc.bleNotifyFromBelt.listen((String data) {_parserInputController.sink.add(data);});
  }

  void addToParserController1() {
    _parserInputController.sink.add("One");
  }

  void addToParserController2() {
    _parserInputController.sink.add("Two");
  }

  dispose() {
    _parserInputController.close();
  }
}

解决方案

我不想让这个问题没有答案,所以我想指出这个问题的答案在于我发布的另一个问题的答案./p>

为什么会赢?使用Provider/ChangeNotifier/Streambuilder在UI中对NotifyParser渲染进行的任何更改,但会根据服务类进行更改

从回答的问题中得到的关于这个问题的评论.

我阅读了该书,但我并不完全理解问题(您对测试流进行了很多更改,以至于我不知道没有测试的真正问题是什么),但是我看到您也做了同样的事情在BleService内创建一个名为_bloc的BleBeltNotifyParserBloc,我相信这是它不更新UI的原因(出于同样的原因,它在这里不起作用).

在此示例中,我尝试使用带流的Inherited Widget/Bloc体系结构,然后将另一个问题移至Provider/Bloc/Async模型,以尝试弄清楚为什么从BleService bloc发送数据时UI没有更新到NotifyParser Bloc.

我要感谢 https://stackoverflow.com/users/3547212/edwynzn 对链接的回答问题!

I'm trying to make the shift to a bloc / provider architecture for a new flutter project. I've been troubleshooting a problem for a while now where one bloc's streams will render on the UI via StreamBuilder but the other bloc will not. Before I continue on I'd love (and need to) to learn why.

I have two blocs, the first is ble_service. I can call functions from the UI to this bloc (app.dart lines 60-72) connecting to a device and rendering what the characteristic returns in the UI via StreamBuilder (line 98). Simply rendering the returned json payload from the ble device in the UI. This updates quite frequently multiple times a second.

My plan was to have a parser bloc (bleBeltNotifyParser_bloc) that would parse the incoming json payload from the ble_service and then stream from there UI. In ble_service I pass the json payload into parserInputSink, a stream from the Parser Bloc (ble_service line 99). In bleBeltNotifyParser.bloc I'm listening for it on line 21 and pass it to aTest2() where I planned to parse it. I stopped here because I tried to render this data on the UI (app.dart line 108) but no matter what different combination of passing data into the parserInputController the UI only renders the seed data. I confirmed the stream is getting data by printing it on line 28.

I've also confirmed I can get to the Parser bloc from the UI by very simply dropping some data into the stream via buttons (lines 73 & 80). When those buttons are pressed, that data is added to the stream and the UI updates as expected.

Why does StreamBuilder work for blue_service and not bleBeltNotifyParser_bloc? I also tried creating the stream in the service and then listening to it in the parser. No luck their either.

My main.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  /// Starting here, everything is used regardless of dependencies
  var blocProvider = BlocProvider(
    bleBeltNotifyParserBloc: BleBeltNotifyParserBloc(),
    bleService: BleService(),

  );
  
  runApp(
    AppStateContainer(
      blocProvider: blocProvider,
      child:  App(),
    ),
  );
}

My AppState

import 'package:flutter/material.dart';
import 'package:flutterappbelt3/main.dart';
import 'package:flutterappbelt3/blocs/ble_service.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';

class AppStateContainer extends StatefulWidget {
  final Widget child;
  final BlocProvider blocProvider;
  const AppStateContainer({
    Key key,
    @required this.child,
    @required this.blocProvider,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => AppState();

  static AppState of(BuildContext context) {
    return (context.inheritFromWidgetOfExactType(_AppStoreContainer) as _AppStoreContainer).appData;
  }
}

class AppState extends State<AppStateContainer> {
  BlocProvider get blocProvider => widget.blocProvider;

  @override
  Widget build(BuildContext context) {
    return _AppStoreContainer(
      appData: this,
      blocProvider: widget.blocProvider,
      child: widget.child,
    );
  }

  void dispose() {
    super.dispose();
  }

}

class _AppStoreContainer extends InheritedWidget {
  final AppState appData;
  final BlocProvider blocProvider;

  _AppStoreContainer({
    Key key,
    @required this.appData,
    @required child,
    @required this.blocProvider,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(_AppStoreContainer oldWidget) => oldWidget.appData != this.appData;
}

class BlocProvider {
  BleBeltNotifyParserBloc bleBeltNotifyParserBloc = BleBeltNotifyParserBloc();
  BleService bleService;

  BlocProvider({
    @required this.bleBeltNotifyParserBloc,
    @required this.bleService,

  });
}

My app.dart

import 'package:flutter/material.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';
import 'blocs/app_state.dart';
import 'blocs/ble_service.dart';

class App extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Position App',
      theme: new ThemeData(
        primarySwatch: Colors.red,
      ),
      home: PositionApp(),
    );
  }
}

class PositionApp extends StatefulWidget {
  @override
  _PositionAppState createState() => _PositionAppState();
}

class _PositionAppState extends State<PositionApp> {

  BleService _service = BleService();
  BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  @override
  void initState() {
    super.initState();
     //_service.startScan();
    //_service.bleNotifyFromBelt.listen((String data) {_bloc.parserInputSink.add(data);});
  }

  @override
  Widget build(BuildContext context) {
    //SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.dark);
    BleService _bleServiceBloc = AppStateContainer.of(context).blocProvider.bleService;
    BleBeltNotifyParserBloc _bleBeltNotifyParserBloc = AppStateContainer.of(context).blocProvider.bleBeltNotifyParserBloc;
    return Scaffold(
      appBar: AppBar(
        title: Text("Position"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Container(
              child: Text("hello"),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.startScan();
              },
                child: Text("Scan & Connect"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.discoverServices();
              },
                child: Text("discover services"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleServiceBloc.disconnectFromDevice();
              },
                child: Text("disconnect"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.addToParserController1();
              },
                child: Text("Parser One"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.addToParserController2();
              },
                child: Text("Parser Two"),
              ),
            ),
            Container(
              child: FlatButton(onPressed: () {
                _bleBeltNotifyParserBloc.aTest();
              },
                child: Text("aTest"),
              ),
            ),
            Container(
                child: StreamBuilder(
                    initialData: "0",
                    stream: _bleServiceBloc.bleNotifyFromBelt,
                    builder: (BuildContext context, AsyncSnapshot snapshot) {
                      if(snapshot.data == null) return CircularProgressIndicator();
                      else return Text(
                        snapshot.data.toString(),
                        style: TextStyle(fontSize: 14.0, color: Colors.black),
                        textAlign: TextAlign.center,
                      );}
                ),
              ),
            Container(
              child: StreamBuilder(
                  initialData: "0",
                  stream: _bleServiceBloc.bleStatusFromBelt,
                  builder: (BuildContext context, AsyncSnapshot snapshot) {
                    if(snapshot.data == null) return CircularProgressIndicator();
                    else return Text(
                      snapshot.data.toString(),
                      style: TextStyle(fontSize: 14.0, color: Colors.black),
                      textAlign: TextAlign.center,
                    );}
              ),
            ),
          ],
        ),
      ),
    );
  }
}

My ble_service.dart


import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'dart:convert' show utf8;
import 'package:rxdart/rxdart.dart';
import 'package:flutterappbelt3/blocs/bleBeltNotifyParser_bloc.dart';

class BleService {

//BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  final String TARGET_DEVICE_NAME = "ESP32";
  final String SERVICE_UUID = "4fafc201-1fb5-459e-8fcc-c5c9c331914b";
  final String NOTIFY_UUID = "beb5483e-36e1-4688-b7f5-ea07361b26a8";
  final String WRITE_UUID = "724b0547-3747-4c00-9710-5305a020018f";
  FlutterBlue flutterBlue = FlutterBlue.instance;
  StreamSubscription<ScanResult> scanSubScription;
  BluetoothDevice beltDevice;
  BluetoothCharacteristic characteristicNotify;
  BluetoothCharacteristic characteristicWrite;
  String bleNotifyString = "";

  BleBeltNotifyParserBloc _bloc = BleBeltNotifyParserBloc();

  BehaviorSubject<String> _bleStatusFromBeltController = BehaviorSubject<String>.seeded("BLE STATUS");
  Stream<String> get bleStatusFromBelt => _bleStatusFromBeltController.stream;

  StreamController<String> _bleNotifyFromBeltController = BehaviorSubject<String>.seeded("BLE NOTIFY");
  Stream<String> get bleNotifyFromBelt => _bleNotifyFromBeltController.stream;
  Sink<String> get bleNotifyFromBeltSink => _bleNotifyFromBeltController.sink;

  BleService();

  dispose() {
    _bleStatusFromBeltController.close();
    _bleNotifyFromBeltController.close();
  }

  startScan() {
    //stopScan();
//    // SCANNING
    scanSubScription = flutterBlue.scan().listen((scanResult) async {
      if (scanResult.device.name == TARGET_DEVICE_NAME) {
        stopScan();
//        // FOUND
        beltDevice = await Future.value(scanResult.device).timeout(const Duration(seconds: 3));
        connectToDevice();
      }
    }, onDone: () => stopScan());
  }

  stopScan() {
    flutterBlue.stopScan();
    scanSubScription?.cancel();
    scanSubScription = null;
    _bleStatusFromBeltController.add("Disconnected");
    print("print Disconnected");
  }

  connectToDevice() async {
    if (beltDevice == null) return;
    // CONNECTING
    await beltDevice.connect();
    beltDevice.requestMtu(185);
    print('print DEVICE CONNECTED');
    print(" print BeltDevice $beltDevice");
    _bleStatusFromBeltController.add("Connected");
    print("print Connected");
    //discoverServices();
  }

  discoverServices() async {
    print("discoverServices beltDevice name is  $beltDevice");
    if (beltDevice == null) return;
    List<BluetoothService> services = await beltDevice.discoverServices();
    services.forEach((service) {
      // do something with service
      if (service.uuid.toString() == SERVICE_UUID) {
        service.characteristics.forEach((characteristic) {
          // set up notify characteristic
          print("Service Found for $characteristic");
          if (characteristic.uuid.toString() == NOTIFY_UUID) {
            characteristicNotify = characteristic;
            // tell characteristic on server to notify
            characteristicNotify.setNotifyValue(true);
            print("notify set to true");
            // listen, convert and put notify value in stream
            characteristicNotify.value.listen((value) {
              bleNotifyString = utf8.decode(value);
              //print("got characteristic $value");
              print(bleNotifyString);
              _bleNotifyFromBeltController.sink.add(bleNotifyString);
              _bloc.parserInputSink.add(bleNotifyString);
            });
            // COMMUNICATING
          }
          // Prepares characteristic for Write
          if (characteristic.uuid.toString() == WRITE_UUID) {
            characteristicWrite = characteristic;
          }
        });
      }
    });
  }
  disconnectFromDevice() {
    //if (beltDevice == null) return;
    //stopScan();
    beltDevice.disconnect();
    _bleStatusFromBeltController.add("Disconnect");
    print("Disconnect");
    // DISCONNECTED
  }
}

My bleBeltNotifyParser_bloc I can not render

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
import 'dart:math' as Math;
import 'package:flutterappbelt3/blocs/ble_service.dart';


class BleBeltNotifyParserBloc{

 // final BleService _bloc = BleService();

  StreamController<String> _parserInputController = BehaviorSubject<String>.seeded("Parser Input");
  Stream<String> get parserInput => _parserInputController.stream;
  Sink<String> get parserInputSink => _parserInputController.sink;

  BleBeltNotifyParserBloc(){


    _parserInputController.stream.listen(_aTest2);

    //_bloc.bleNotifyFromBelt.listen((String data) {parserInputSink.add(data); print('Got eem! Input Parser $data');}); Tried various things - such as listening to streams originating from ble_service.


  }

  void _aTest2(data) {
    print("WHAT!!! $data");
  }

  void aTest() {
    //_bloc.bleNotifyFromBelt.listen((String data) {_parserInputController.sink.add(data);});
  }

  void addToParserController1() {
    _parserInputController.sink.add("One");
  }

  void addToParserController2() {
    _parserInputController.sink.add("Two");
  }

  dispose() {
    _parserInputController.close();
  }
}

解决方案

I didn't want to leave this question unanswered so I wanted to point out the answer to this question lies in the answer to this other question I posted.

Why won't any changes from NotifyParser render in the UI using Provider / ChangeNotifier / Streambuilder but will from a Service Class

A comment from that answered question that refers to this question.

I read it but I don't fully understand the problem (you made a lot of changes to test the stream that I don't know what was the real issue without the tests) but I saw you did the same thing by creating a BleBeltNotifyParserBloc called _bloc inside BleService, and I believe that was the reason it didn't update the UI (for the same reason it didn't work here).

In this example I was trying an Inherited Widget / Bloc architecture with streams and then moved in the other question to a Provider / Bloc / Async model to try and figure out why the UI was not updating when sending data from the BleService bloc to the NotifyParser Bloc.

I need to thank https://stackoverflow.com/users/3547212/edwynzn for his answer on the linked question!!

这篇关于Flutter Bloc A在Bloc B中添加流,但是此流将不会通过StreamBuilder在UI中呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆