【发布时间】:2021-03-01 03:47:47
【问题描述】:
当我使用 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{}
【问题讨论】:
-
不确定,但您是否创建了该集团的第二个实例?在这种情况下,您必须将 bloc 实例作为参数传递
-
其中 bloc 的第二个实例,只需在 Amar() 函数中使用它,即可接收来自服务器的事件以将该事件添加到 bloc ,并且该事件实际上转换为状态和过渡工作,但不重建与状态相对应的用户界面......我希望能帮助PLZ