flutter开发实战-事件总线EventBus实现

flutter开发实战-事件总线EventBus实现

在开发中,经常会需要一个广播机制,用以跨Widget事件通知。
事件总线 实现了订阅者模式,订阅者模式包含发布者和订阅者两种角色,可以通过事件总线来触发事件和监听事件。

一、自定义事件总线

实现eventBus

typedef AppEventCallback = void Function(dynamic arg);

// 事件总线
// 订阅者回调签名
class AppEventBus {
    
    
  //私有构造函数
  AppEventBus._internal();

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

  //工厂构造函数
  factory AppEventBus() => _singleton;

  //保存事件订阅者队列,key:事件名(id),value: 对应事件的订阅者队列
  //Map<eventName, Map<hashCode, List[]>>
  final _emap = Map<Object, Map<String, List<AppEventCallback>?>>();

  // final _emap = Map<Object, List<GamePrizeEventCallback>?>();

  //添加订阅者
  void on(eventName, Object object, AppEventCallback f) {
    
    
    String hashCode = object.hashCode.toString();
    Map<String, List<AppEventCallback>?>? map = _emap[eventName];
    if (map == null) {
    
    
      map = Map<String, List<AppEventCallback>?>();
      _emap[eventName] = map;
    }

    map[hashCode] ??= <AppEventCallback>[];
    map[hashCode]!.add(f);
  }

  //移除订阅者
  void off(eventName, Object object, [AppEventCallback? f]) {
    
    
    String hashCode = object.hashCode.toString();
    Map<String, List<AppEventCallback>?>? map = _emap[eventName];
    if (map != null) {
    
    
      var list = map[hashCode];
      if (list == null) return;
      if (f == null) {
    
    
        map[hashCode] = null;
      } else {
    
    
        list.remove(f);
      }
    }
  }

  //触发事件,事件触发后该事件所有订阅者会被调用
  void emit(eventName, [arg]) {
    
    
    Map<String, List<AppEventCallback>?>? map = _emap[eventName];
    if (map != null) {
    
    
      for (String hashCode in map.keys) {
    
    
        List<AppEventCallback>? list = map[hashCode];
        if (list != null && list.isNotEmpty) {
    
    
          int len = list.length - 1;
          //反向遍历,防止订阅者在回调中移除自身带来的下标错位
          for (var i = len; i > -1; --i) {
    
    
            list[i](arg);
          }
        }
      }
    }
  }
}

二、使用event_bus库

在工程的pubspec.yaml引入库

  # enent_bus
  event_bus: ^2.0.0
  • 1.使用event_bus库

创建一个EventBus实例并使其可用于其他类。
通常每个应用程序只有一个事件总线,但可以设置多个事件总线来对特定的事件集进行分组。

import 'package:event_bus/event_bus.dart';

EventBus eventBus = EventBus();
  • 2.定义事件
class UserLoggedInEvent {
    
    
  User user;

  UserLoggedInEvent(this.user);
}

class NewOrderEvent {
    
    
  Order order;

  NewOrderEvent(this.order);
}
  • 3.注册监听者
// 特定事件监听
eventBus.on<UserLoggedInEvent>().listen((event) {
    
    
  // All events are of type UserLoggedInEvent (or subtypes of it).
  print(event.user);
});

// 所有事件监听
eventBus.on().listen((event) {
    
    
  // Print the runtime type. Such a set up could be used for logging.
  print(event.runtimeType);
});
  • 4.触发事件
User myUser = User('Mickey');
eventBus.fire(UserLoggedInEvent(myUser));

三、小结

flutter开发实战-事件总线EventBus实现,主要用于广播机制,跨Widget事件通知。

学习记录,每天不停进步。

猜你喜欢

转载自blog.csdn.net/gloryFlow/article/details/131634651
今日推荐