Flutter event_bus 发布/订阅 总线

2022-04-06 19:06:21 浏览数 (1)

最近在捣鼓Flutter的时候, 一直在解决有关fileProvider的问题. 当需要打开安卓设备自带的文件管理器时, 一直报错

exposed beyond app through Intent.getData() 在配置 FileProvider相关权限后, 依旧不行, 貌似需要原生调用.这估计就需要flutter与原生相互调用了, 奈何我暂时没有了解过有关原生开发的信息. 就只能先去解决一些页面交互的问题.

event_bus

Flutter 的event_bus扩展, 可以简单的实现一个 发布<->订阅 模型. 如果需要其他的跨组建数据共享, 则可以选择 Provider 扩展.

举个例子, 当我们在 login.dart 中登录后, 需要在 user.dart 中更新信息时. 我们可以直接在 user.dart 中订阅一个事件, 当用户在 login.dart 中登录后发布一个信息, user.dart中监听到事件则重新获取用户信息, 重新渲染页面.

实现

目前 我需要的场景是, 当用户登录后, 直接返回首页, 刷新信息.

大致的文件结构为:

代码语言:javascript复制
|_ main.dart
|_ account |_ login.dart 
|
|_ home    |_ index.dart
|          |_ home.dart
|          |_ user.dart
|
|_ event   |_ bus.dart
           |_ account_event.dart

其中 main.dart 是我们的启动文件, account/login 为登录页面, home/index 为首页的 入口文件, 有 user 和 home 两个tab.

首先 我们可以新建一个 ~/event/bus.dart 文件, 来全局共享 EventBus 类

代码语言:javascript复制
import 'package:event_bus/event_bus.dart';

// event/bus.dart
class Bus {
  static late EventBus eventBus;

  static init() {
    Bus.eventBus = EventBus();
  }
}

接着在 main.dart 中初始化 event_bus

代码语言:javascript复制
/* code */
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  Bus.init();

  runApp(const App());
}

在发布/订阅消息时, 我们需要一个模型来指定参数, 比如这里 我们只需要一个简单的登录通知 >

代码语言:javascript复制
class AccountEvent {
  final String type;

  const AccountEvent(this.type);
}

接着 我们可以在需要的页面(user.dart)订阅通知 >

代码语言:javascript复制
 import 'package:example/event/account_event.dart';
 import 'package:example/event/bus.dart';
 
 /* code */

 Future<void> _listen() async {
     Bus.eventBus.on<AccountEvent>().listen((event) {
        LogUtil.v(event.type)
        /* code */
     });
 }

此时 当用户登录后, 我们可以直接 通过 EventBus.fire 发布信息

代码语言:javascript复制
 import 'package:example/event/account_event.dart';
 import 'package:example/event/bus.dart';
 
 Future<void> _login() async {
   httpR.post('/login',{
     'user': xx,
     'pass': xx,
   }).then((res) async {
     if (res['code'] == 0){
        prefs.setString('token', res['token']); // 存储凭证
        Bus.eventBus.fire(const AccountEvent('login'));
        Navigator.of(context).pop();
     }
   })
 }

此时, 当用户登录后, 在user.dart中 我们期待会返回一个 内容为 'login' 字符串

本文链接:https://blog.xsot.cn/archives/flutter_event_bus.html

所有原创文章采用 CC BY-NC-SA 4.0 协议进行许可, 转载请注明原文链接

0 人点赞