Flutter事件总线插件flutter_bus的使用
Flutter事件总线插件flutter_bus的使用
FlutterBus 是一个用于 Flutter 应用的静态事件总线库。它由 Mindful Software 的 Michael Bushe 制作,灵感来源于广泛使用的 Swing EventBus。
这是 beta 版本的 API,可能会发生变化。虽然它简单小巧,但以下几点反馈尤其受欢迎:
-
initialData
是否应该作为FlutterBusBuilder
的属性?
它看起来像FutureBuilder
,有时你希望有一个初始事件。然而,“向一个部件发布”违背了发布/订阅模式。 -
on()
方法是否应返回StreamSubscription
?
它可能太泄露了,但暂停/恢复/取消显然是有用的。可以返回更小的接口。 -
主题(
Subject
)在事件总线中经常有用。
例如,在应用启动时发布ThemeChangedEvent
,以替代FlutterBusBuilder
中的初始数据。该事件可以保存为最后一种类型的事件,并且新订阅者可以收到之前的值,这样默认主题可以通过事件而不是部件设置。
示例
深度服务中的事件发布
FlutterBus.publish(TickerUpdateEvent('GOOG', 91.66));
在 Widget 树中的事件监听
FlutterBusBuilder<TickerUpdateEvent>(
builder: (context, tickerUpdateEvent) {
return TickerWidget(tickerUpdateEvent.ticker, tickerUpdateEvent.price);
}
);
示例目录中的两个示例演示
1. FlutterBus 计数器
计数器文本与应用程序的其他部分完全解耦。它只有三个导入:
import 'package:flutter/material.dart';
import 'package:flutter_bus/flutter_bus.dart';
import 'counter_increment_event.dart';
- 它知道感兴趣的事件。
- 它知道 FlutterBus。
- 它知道如何在 Material 中绘制自己。
它不需要很多知识,这对一个部件来说是一个巨大的成就。它不需要 Locator。它不需要通过 Provider 或 InheritedWidget 提供的任何对象。它是树的独立部分。可以将部件移动到其他位置,而无需担心其父部件是什么。
2. FlutterBus 主题切换器
第二个示例展示了 FlutterBusBuilder
的用法。每当有新的感兴趣类型事件发布时,FlutterBusBuilder
都会构建一个新的部件。
@override
Widget build(BuildContext context) {
return FlutterBusBuilder<ThemeChangedEvent>(
builder: (context, themeEvent) {
// 如果没有提供 initialData,则第一次构建时事件将为 null
ThemeData lightTheme;
ThemeData darkTheme;
if (themeEvent == null) {
lightTheme = ThemeData.light();
darkTheme = ThemeData.dark();
} else {
lightTheme = themeEvent.lightTheme;
darkTheme = themeEvent.darkTheme;
}
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'FlutterBus ThemeChangedEvent Demo',
theme: lightTheme,
darkTheme: darkTheme,
home: const MyHomePage(title: 'FlutterBus ThemeChangedEvent Demo'),
);
},
);
}
为什么使用 FlutterBus?
使用 FlutterBus 可以保持组件之间的解耦。事件总线模式在 UI 中很常见,但也许不够普遍。
为什么选择 FlutterBus 而不是其他 EventBus 库?很简单,因为 FlutterBus 是为单个 Flutter 应用设计的一个流(总线),并带有帮助部件使用 FlutterBus 的 FlutterBusBuilder
。其他 EventBus 库更为通用,因此不那么简洁。
谨慎地应用 FlutterBus 模式。它并不适用于所有情况(至少在没有深思熟虑和设计的情况下不适合)。
FlutterBus
最适合封装 UI 动作到事件 API 中。ThemeChangedEvent
和 CounterChangedEvent
是很好的例子。ThemeChangedEvent
是部件到部件的事件,封装了一个 UI API。CounterChangedEvent
是“业务逻辑”事件——对于计数器应用来说,业务就是改变计数器。
只有一个流处理所有事件类型,因此非常高效。
考虑为事件架构两个流和两个 EventBus:
- 使用
FlutterBus
来处理从部件到部件或 UI 服务到部件的事件。 - 使用 EventBus 或 Dart Event Bus 来处理从 UI 服务层到服务层的事件,这些事件来自用户交互或网络响应,然后使用 FlutterBus 公告更改。
FlutterBus 和 Dart Event Bus 几乎完全相同,唯一的区别是 FlutterBus 是在整个 Flutter 应用程序中可访问的单个静态总线。不能有两个 FlutterBus
。这没有意义——只有一个 UI 运行在一个进程中。
FlutterBus 简洁且更适合 Flutter 应用的目的:
// 对比其他 EventBus 的复杂性
EventBus eventBus = (Provider 提供它,GetIt 获取它)
_themeStreamSub = eventBus.on<ThemeChangeEvent>().listen((event) {
// 使用 FlutterBus 更简洁
_themeStreamSub = FlutterBus.on<ThemeChangeEvent>((event) {
更多关于Flutter事件总线插件flutter_bus的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter事件总线插件flutter_bus的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
flutter_bus
是一个轻量级的事件总线插件,用于在 Flutter 应用中实现组件之间的通信。它允许你在不同的部件(Widgets)之间发送和接收事件,而不需要直接引用或依赖彼此。
安装
首先,你需要在 pubspec.yaml
文件中添加 flutter_bus
依赖:
dependencies:
flutter:
sdk: flutter
flutter_bus: ^1.0.0
然后运行 flutter pub get
来安装依赖。
基本用法
1. 创建事件总线
你可以在应用的顶层创建一个事件总线实例:
import 'package:flutter_bus/flutter_bus.dart';
final eventBus = FlutterBus();
2. 发送事件
你可以通过 eventBus
发送事件。事件可以是任何对象,通常是一个简单的 class
。
class MyEvent {
final String message;
MyEvent(this.message);
}
eventBus.post(MyEvent('Hello, Flutter Bus!'));
3. 接收事件
你可以通过订阅事件总线来接收事件。通常,你会在 StatefulWidget
的 initState
方法中订阅,并在 dispose
方法中取消订阅。
import 'package:flutter/material.dart';
import 'package:flutter_bus/flutter_bus.dart';
class MyListenerWidget extends StatefulWidget {
[@override](/user/override)
_MyListenerWidgetState createState() => _MyListenerWidgetState();
}
class _MyListenerWidgetState extends State<MyListenerWidget> {
String _message = '';
[@override](/user/override)
void initState() {
super.initState();
eventBus.on<MyEvent>().listen((event) {
setState(() {
_message = event.message;
});
});
}
[@override](/user/override)
void dispose() {
eventBus.destroy(this);
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Text(_message);
}
}
4. 取消订阅
为了避免内存泄漏,你需要在 dispose
方法中取消订阅事件总线。
eventBus.destroy(this);
完整示例
以下是一个完整的示例,展示了如何使用 flutter_bus
在不同的部件之间发送和接收事件。
import 'package:flutter/material.dart';
import 'package:flutter_bus/flutter_bus.dart';
void main() {
runApp(MyApp());
}
final eventBus = FlutterBus();
class MyApp extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter Bus Example')),
body: Column(
children: [
MySenderWidget(),
MyListenerWidget(),
],
),
),
);
}
}
class MySenderWidget extends StatelessWidget {
[@override](/user/override)
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
eventBus.post(MyEvent('Hello, Flutter Bus!'));
},
child: Text('Send Event'),
);
}
}
class MyListenerWidget extends StatefulWidget {
[@override](/user/override)
_MyListenerWidgetState createState() => _MyListenerWidgetState();
}
class _MyListenerWidgetState extends State<MyListenerWidget> {
String _message = '';
[@override](/user/override)
void initState() {
super.initState();
eventBus.on<MyEvent>().listen((event) {
setState(() {
_message = event.message;
});
});
}
[@override](/user/override)
void dispose() {
eventBus.destroy(this);
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Text(_message);
}
}
class MyEvent {
final String message;
MyEvent(this.message);
}