event_bus的主要作用是各组件间的通信,能有效的分离事件发送方和接收方(解耦),类似通知。
导入event_bus
可以通过添加依赖的方式导入,因为代码不多,我就直接创建个文件把代码复制进去了,下面是event_bus版本号2.0.0的源代码
import 'dart:async';
/// Dispatches events to listeners using the Dart [Stream] API. The [EventBus]
/// enables decoupled applications. It allows objects to interact without
/// requiring to explicitly define listeners and keeping track of them.
///
/// Not all events should be broadcasted through the [EventBus] but only those of
/// general interest.
///
/// Events are normal Dart objects. By specifying a class, listeners can
/// filter events.
///
class EventBus {
StreamController _streamController;
/// Controller for the event bus stream.
StreamController get streamController => _streamController;
/// Creates an [EventBus].
///
/// If [sync] is true, events are passed directly to the stream's listeners
/// during a [fire] call. If false (the default), the event will be passed to
/// the listeners at a later time, after the code creating the event has
/// completed.
EventBus({bool sync = false})
: _streamController = StreamController.broadcast(sync: sync);
/// Instead of using the default [StreamController] you can use this constructor
/// to pass your own controller.
///
/// An example would be to use an RxDart Subject as the controller.
EventBus.customController(StreamController controller)
: _streamController = controller;
/// Listens for events of Type [T] and its subtypes.
///
/// The method is called like this: myEventBus.on<MyType>();
///
/// If the method is called without a type parameter, the [Stream] contains every
/// event of this [EventBus].
///
/// The returned [Stream] is a broadcast stream so multiple subscriptions are
/// allowed.
///
/// Each listener is handled independently, and if they pause, only the pausing
/// listener is affected. A paused listener will buffer events internally until
/// unpaused or canceled. So it's usually better to just cancel and later
/// subscribe again (avoids memory leak).
///
Stream<T> on<T>() {
if (T == dynamic) {
return streamController.stream as Stream<T>;
} else {
return streamController.stream.where((event) => event is T).cast<T>();
}
}
/// Fires a new event on the event bus with the specified [event].
///
void fire(event) {
streamController.add(event);
}
/// Destroy this [EventBus]. This is generally only in a testing context.
///
void destroy() {
_streamController.close();
}
}
创建event_bus对象(发送端)
final EventBus eventBus = EventBus();
监听相应的响应事件(接收端,可以放在initState()中)
_event = eventBus.on<类型>().listen((event) {
//接收数据并按需更新界面
setState(() { });
});
销毁event_bus对象(接收端,放在dispose()中)
_event.dispose();
发出事件(发送端)
eventBus.fire(传递的数据)
至此就结束了,so easy…下面是一个小demo:
//创建EventBus对象
final EventBus eventBus = EventBus();
//传递的对象
class GCUserInfo {
GCUserInfo(this.name, this.age);
final String name;
final int age;
}
class EventBusApp extends StatelessWidget {
const EventBusApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: GCHomePage(),
);
}
}
class GCHomePage extends StatelessWidget {
const GCHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("EventBus"),),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextButton(onPressed: (){
final userInfo = GCUserInfo("Steven", Random().nextInt(100));
//发出事件
eventBus.fire(userInfo);
}, child: Text("按钮", style: TextStyle(fontSize: 18),)),
GCText()
],
),
),
);
}
}
class GCText extends StatefulWidget {
const GCText({Key? key}) : super(key: key);
@override
State<GCText> createState() => _GCTextState();
}
class _GCTextState extends State<GCText> {
String info = "Hello world!";
late final _event;
@override
void initState() {
// TODO: implement initState
super.initState();
//3.监听相应类型的事件
_event = eventBus.on<GCUserInfo>().listen((event) {
setState(() {
info = "${event.name}-----${event.age}";
});
});
}
@override
Widget build(BuildContext context) {
return Text(info, style: TextStyle(fontSize: 18),);
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_event.dispose();
}
}