今天,我们分别使用 EventBus 和 provider ,来写一个事件分发,数据通信的demo。
EventBus
事件分发,通过 Stream 流实现。我们主要用到如下方法:
- fire() 发送事件
- on() 为广播监听,都是对 Stream 流操作
使用
- 添加引用
dependencies:
event_bus: ^1.1.1
- 简单的对 eventBus 进行一层封装,通常每个应用只有一个事件总线:
//全局的 EventBus
class EventBusManager {
EventBus _eventBus = EventBus();
EventBusManager._privateConstructor();
static final EventBusManager _busManager =
EventBusManager._privateConstructor();
factory EventBusManager() {
return _busManager;
}
static EventBusManager get instance {
return _busManager;
}
static EventBus get eventBus {
return _busManager._eventBus;
}
static void onDestroy() {
eventBus.destroy();
}
}
- 使用方式非常简单
event定义事件:
//数值更新的事件
class ValueChangeEvent {
final String value;
ValueChangeEvent(this.value);
}
event 发送事件:
EventBusManager.eventBus.fire(ValueChangeEvent("hello world"));
event 接收事件:
EventBusManager.eventBus.on<ValueChangeEvent>().listen((event) {
...//接收到事件后的逻辑处理
});
- event销毁,为了防止内存泄漏,一般在应用销毁时都需要对 EventBus 进行销毁:
EventBusManager.onDestroy()
Provider
InheritedWidget 组件的上层封装,与 Notifier 结合使用。
之前我们分析过其实现方式,有兴趣的同学可以看看自定义InheritedProvider 数据驱动模型
使用方式:
- 添加引用
dependencies:
provider: ^4.3.3
- 定义共享数据模型,注意:bean 需要继承 ChangeNotifier ,在数据源变化时,需调用 notifyListeners 方法,例如:
//数据模型,名称是随意起的
class ProviderDataNotifier with ChangeNotifier {
String _value = "";
String get value => _value;
updateValue(String data) {
_value = data;
//固定写法,属性变更需通知依赖项时,需调用通知方法
notifyListeners();
}
}
- 附上demo代码:
在父控件注册共享数据源, 就是刚刚继承了ChangeNotifier的数据模型对象
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ProviderDataNotifier())
],
child: Center(
child: ChildWidget(), //代码再下方附上
),
)
使用 Comsumer<T> 对共享数据模型进行监听,当 notifyListeners 被调用后,会触发 builder(context, data, _)。data 就是泛型共享数据 ProviderDataNotifier
class ChildWidget extends StatelessWidget {
const ChildWidget({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<ProviderDataNotifier>(
builder: (context, data, _) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(
child: Text('发送Event随机数'),
onPressed: () {
final randomValue = Random().nextInt(10).toString();
//直接对共享数据实体进行操作,通过 notifyListeners 方法,会重新触发 builder 方法
data.updateValue(randomValue);
},
),
//显示data数据
Text(data.value),
],
);
},
);
}
}
在维护轻量级数据场景时,除了Bloc,eventBus 和 provider 也是个不错的选择方法。