Flutter -- 事件广播机制

861 阅读1分钟

原生实现三步曲

事件总线通常实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色。

a.抽象类的定义

//发布者
abstract class MyPublisher {
  void post<T>(T event);
}
//订阅者
typedef MySubscriber<T> = void Function(T event);
//抽象类继承
abstract class _EventBus extends MyPublisher {
  void register<T>(MySubscriber<T> subscriber);
  void unregister<T>(MySubscriber<T> subscriber);
}

b.接口的实现

class MyEventBus implements _EventBus {
  //私有构造函数
  MyEventBus._internal();

  //保存单例
  static MyEventBus _singleton = MyEventBus._internal();

  //工厂构造函数
  factory MyEventBus()=> _singleton;
  
  List<Function> subscribers = new List();

  @override
  register<T>(MySubscriber<T> subscriber) {
    if (!subscribers.contains(subscriber)) {
      subscribers.add(subscriber);
    }
  }

  @override
  unregister<T>(MySubscriber<T> subscriber) {
    if (subscribers.contains(subscriber)) {
      subscribers.remove(subscriber);
    }
  }

  @override
  post<T>(T event) {
    var ints = subscribers.whereType<MySubscriber<T>>();
    ints?.forEach((subscriber) => subscriber?.call(event));
  }
}

c.用法

场景:点击按钮,使得页面数字加一

//定义事件A
class EventA {int count = 0;}
//按钮的点击

var event = EventA();
void _onTap() {
  event.count++;
  MyEventBus().post(event);
}
//定阅者初始化
@override
void initState() {
  super.initState();
  _subscriber = (EventA: event) => setState(() => _count = event.count);
 //注册
  MyEventBus().register<EventA>(_subscriber);
}

Pub上的插件库: Github地址 -- EventBus

class GlobalHelper {
  //私有构造函数
  GlobalHelper._internal();

  //保存单例
  static GlobalHelper _singleton = GlobalHelper._internal();

  //工厂构造函数
  factory GlobalHelper()=> _singleton;
  
  static EventBus eventBus = EventBus(sync: true);
}

自定义event事件

//可以添加需要的属性值
class MyEvent {
  MyEvent();
}

自定义的事件监听

GlobalHelper.eventBus.on<MyEvent>().listen((event) async {
  //do something
});

事件的触发或发布

GlobalHelper.eventBus.fire(MyEvent());

这样整个事件的广播机制就完成了。

EventBus中的实现机制

/// 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.

主要是用到了dart中的Stream:

StreamController _streamController;

关于Stream可以看下一篇文章介绍