首页 > 解决方案 > 事件已添加到 Bloc 和 yield 状态,但它不召回 bloc builder

问题描述

当我使用 BlocProvider.of<> 从无状态小部件添加事件时,它确实添加了事件和屈服状态,并BlocBuilder工作和更改 UI,

但是,当从一个单独的类中添加一个事件时,它确实将一个事件添加到 bloc 并onTransition工作,但不会产生新的状态,BlocBuilder也不能改变 UI。

主要的 :

main(){
return runApp(MyApp());
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
 MQTTManager x = MQTTManager();
 return MaterialApp(
   home: BlocProvider(
     lazy: false,
     create:(context)=>MqttblocBloc(MQTTManager())..add(StartConnect()) ,
     child:Home() ,
   ),
 );
}
}

集团:

class MqttblocBloc extends Bloc<MqttblocEvent, MqttblocState> {
  MQTTManager manager = MQTTManager() ;
  MqttblocBloc(this.manager) : super(MqttblocInitial());

 @override
 Stream<MqttblocState> mapEventToState(
   MqttblocEvent event,
 ) async* {
   if(event is StartConnect){
    try{
      manager.initializeMQTTClient();
      manager.connect();
      yield MqttblocInitial();
    }catch(e){
      print(e);
    }
   }

   else if(event is ConnectedEvent) {
     try{
       print('inBloc connect....');
       yield ConnectedState(MQTTManager.s);
     }catch(e){
       print(e);
     }
   }


   else if(event is PublishedEvent){
     try{
       manager.publishsw1('on');
       print('inBloc publish........');
       yield PublishState(manager.getText1());
     }catch(e){
       print(e);
     }
   }

   else if(event is DisconnectedEvent) {
     try{
       print('inBloc And Disconnnnn....');
       yield DisconnectState(MQTTManager.u);
     }catch(e){
       print(e);
     }
   }

 }
 @override
 void onTransition(Transition<MqttblocEvent, MqttblocState> transition) {
   super.onTransition(transition);
   print(transition);
 }
}

在这里我监听服务器并将事件添加到 bloc 的单独类:

class MQTTManager {

  MqttblocBloc bloc ;

  static var s ;
  static var u ;
  MqttServerClient client;
  String text ;
  String text1 ;
  String text2 ;
  static List<String> conn = [] ;

  void initializeMQTTClient(){
    client = MqttServerClient("broker.shiftr.io","User");
    client.port = 1883;
    
    client.secure = false;
    client.logging(on: true);
    client.onConnected = onConnected;

    final MqttConnectMessage connMess = MqttConnectMessage()
        .authenticateAs('889514b9', 'd5459e3f6b0422cb')
        .withClientIdentifier("User")
        .withWillTopic('willtopic') 
        .withWillMessage('My Will message')
        .startClean() // Non persistent session for testing
        .withWillQos(MqttQos.atLeastOnce);
    print('EXAMPLE::Mosquitto client connecting....');
    client.connectionMessage = connMess;

  }
  // Connect to the host
  void connect() async{
    assert(client != null);
    try {
      print('EXAMPLE::Mosquitto start client connecting....');
      await client.connect();
      Amar(); // <...... here calling this fun to start listen to Server
    } on Exception catch (e) {
      print('EXAMPLE::client exception - $e');
      disconnect();
    }
  }

  void disconnect() {
    print('Disconnected');
    client.disconnect();
  }

  void publishsw1(String message){
    final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
    builder.addString(message);
    client.publishMessage('hello/sw1', MqttQos.exactlyOnce, builder.payload);

  }
  void onConnected() {

    print('EXAMPLE::shiftr client connected....');

    client.subscribe("hello/sw1", MqttQos.atLeastOnce);

    client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
      final MqttPublishMessage recMess = c[0].payload;
      final String pt =
      MqttPublishPayload.bytesToStringAsString(recMess.payload.message);
      setText(pt);

    });

  }

   Amar() { //<....... here h listen to server 
     bloc =  MqttblocBloc(this);
     client.subscribe("\$events", MqttQos.atLeastOnce);

    client.updates.listen((List<MqttReceivedMessage<MqttMessage>> c) {
      final MqttPublishMessage recMess = c[0].payload;
      final String pt =
      MqttPublishPayload.bytesToStringAsString(recMess.payload.message);

      var z =  DetectEvent.fromJson(json.decode(pt));
      if(z.type == 'connected'){
        var connected = Connected.fromJson(json.decode(pt));
        print (connected.type);
        bloc.add(ConnectedEvent()); // <... here I add event to Bloc , but it not changeing UI  

      }
      else if(z.type == 'disconnected'){
        var disconnected = Disconnected.fromJson(json.decode(pt));
        print (disconnected.type) ;
        bloc.add(DisconnectedEvent()); // <... here I add event to Bloc , but it not changeing UI  

      }
      else if(z.type == 'published'){
        var published = Published.fromJson(json.decode(pt));
        print(published.type) ;
      }
}
}

那是一个无状态的小部件并使用 blocbuider :

class Home extends StatelessWidget {
MQTTManager v = MQTTManager();
  @override
  Widget build(BuildContext context) {
    MqttblocBloc p = BlocProvider.of<MqttblocBloc>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Bloc MQTT'),
        actions: [
          Row(
            children: [
              IconButton(
                icon: Icon(Icons.wb_incandescent,
                ),
                onPressed: (){
                 p.add(PublishedEvent());//<.... here it change UI ,
                },
              ),
            ],
          )
        ],
      ),
      body: Center(
        child: BlocBuilder<MqttblocBloc,MqttblocState>(
         // buildWhen: (previuosState , currentState)=>currentState.runtimeType !=previuosState.runtimeType,

          builder:(context , state){
            if(state is MqttblocInitial){
              return CircularProgressIndicator();
            }
            else if(state is ConnectedState){
              return IconButton(
                icon: Icon(Icons.wifi),
                onPressed: (){},
              );
            }
            else if(state is PublishState){
              return RaisedButton(
                child: Text('${state.x}'),
                onPressed: (){},
              );
            }
            else if(state is DisconnectState){
              return IconButton(
                icon: Icon(Icons.wb_incandescent),
                onPressed: (){
                },
              );
            }
            return CircularProgressIndicator();
          } ,
        ),
      )
    );
  }
}

集团国家:

@immutable
abstract class MqttblocState extends Equatable {
 const MqttblocState();
  @override
  List<Object> get props => [];

}

class MqttblocInitial extends MqttblocState {}

class ConnectedState extends MqttblocState{
  final String x ;
  ConnectedState(this.x);
  @override
  List<Object> get props => [x];
}
class PublishState extends MqttblocState{
  final String x ;
  PublishState(this.x);
  @override
  List<Object> get props => [x];
}

class DisconnectState extends MqttblocState{
  final String x ;
  DisconnectState(this.x);
  @override
  List<Object> get props => [x];
}

和集团事件

@immutable
abstract class MqttblocEvent extends Equatable  {
  MqttblocEvent();
  @override
  List<Object> get props => [];
}

class StartConnect extends MqttblocEvent{}

class ConnectedEvent extends MqttblocEvent{}

class PublishedEvent extends MqttblocEvent{}

class DisconnectedEvent extends MqttblocEvent{}


标签: flutterbloc

解决方案


这就是为什么,您产生相同的状态并使用Equatable没有任何不同的道具进行比较,因此 BlocBuilder 没有看到任何变化。

您有两个解决方案 ether un-inherit Equatable从类MqttblocEvent

 abstract class MqttblocEvent {
  MqttblocEvent();
}

或者在中间产生不同的状态,例如MqrrblocInProgress (Recommended) :

 Stream<MqttblocState> mapEventToState(
   MqttblocEvent event,
 ) async* {
    yield MqrrblocInProgress();
.....

推荐阅读