1. 效果预览
在 Flutter 应用开发中,组件间的通信是一个常见且重要的需求。当涉及到父子组件之间复杂的交互时,使用事件总线(Event Bus)可以有效地实现解耦和灵活的消息传递。本文将通过一段具体的代码,详细介绍如何在 Flutter 中利用事件总线实现父子组件之间的通信。
2. 安装插件
event_bus: ^2.0.0
创建eventBus.dart文件,写入以下内容:
import 'package:event_bus/event_bus.dart';
EventBus eventBus = EventBus();
/// 通知测试
class BusNotificationTest {
int index;
BusNotificationTest(this.index);
}
3. 结构分析
这段代码展示了如何在 Flutter 中通过事件总线实现父子组件之间的通信,具体功能为:在父组件EventBusParentPage中,用户点击按钮后,会触发一个通知事件,子组件EventBusChildPage监听该事件,并根据事件携带的信息改变自身的背景颜色。
- 父组件:EventBusParentPage
/// 事件Bus通知父类
class EventBusParentPage extends StatefulWidget {
const EventBusParentPage({super.key});
EventBusParentPageState createState() => EventBusParentPageState();
}
class EventBusParentPageState extends State<EventBusParentPage> {
/// 颜色索引
int index = 0;
/// 通知变色
void handleColorChange() {
index++;
if (index > 2) {
index = 0;
}
eventBus.fire(BusNotificationTest(index));
}
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: Container(
alignment: Alignment.center,
decoration: const BoxDecoration(color: Colors.white),
child: TextButton(
onPressed: handleColorChange,
child: const Text('点击变色',
style: TextStyle(color: Colors.black, fontSize: 20))))),
const EventBusChildPage()
],
);
}
}
- 组件定义:
- EventBusParentPage是一个有状态组件,通过createState方法返回EventBusParentPageState实例,用于管理组件状态和构建 UI。
- 状态变量:
- index:一个整型变量,用于记录颜色索引,初始值为 0。这个索引将决定子组件最终显示的颜色。
- 事件处理方法:
- handleColorChange:当用户点击父组件中的按钮时,该方法被调用。它首先将index值增加 1,如果index超过 2,则重置为 0。然后,通过事件总线eventBus触发一个BusNotificationTest类型的事件,并将当前的index值作为参数传递给该事件。这里的eventBus应该是在全局或合适的作用域中定义的事件总线实例,BusNotificationTest则是一个自定义的事件类,用于携带数据(这里是颜色索引)。
- 构建 UI:
- 在build方法中,父组件构建了一个垂直方向的Column布局。
- 第一个子组件是一个Expanded包裹的Container,其中包含一个TextButton。按钮的文本为 “点击变色”,当按钮被点击时,会调用handleColorChange方法。Container的背景颜色设置为白色。
- 第二个子组件是EventBusChildPage,这是需要接收事件通知的子组件,通过const关键字创建,意味着它是一个不可变的组件实例。
- 子组件:EventBusChildPage
/// 事件Bus通知子类
class EventBusChildPage extends StatefulWidget {
const EventBusChildPage({super.key});
EventBusChildPageState createState() => EventBusChildPageState();
}
class EventBusChildPageState extends State<EventBusChildPage> {
/// 颜色列表
List<Color> colorList = [Colors.red, Colors.yellow, Colors.blue];
/// 刷新监听
late StreamSubscription<BusNotificationTest> eventBusExample;
/// 背景颜色
late Color bgColor;
void initState() {
super.initState();
bgColor = colorList[0];
// 监听颜色索引变化
eventBusExample = eventBus.on<BusNotificationTest>().listen((event) {
setState(() {
bgColor = colorList[event.index];
});
});
}
void dispose() {
eventBusExample.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 2,
child: Container(color: bgColor, child: null));
}
}
- 组件定义:
- EventBusChildPage同样是一个有状态组件,其createState方法返回EventBusChildPageState实例。
- 状态变量
- colorList:一个包含三种颜色(红色、黄色、蓝色)的列表,用于存储可供选择的背景颜色。
- eventBusExample:一个StreamSubscription类型的变量,用于订阅事件总线eventBus上的BusNotificationTest类型的事件。这里使用late关键字声明,意味着在initState方法中会对其进行初始化。
- bgColor:用于存储子组件当前的背景颜色,初始值为colorList中的第一个颜色(红色),同样使用late关键字声明,在initState方法中初始化。
- 生命周期方法:
- initState:在组件插入到 Widget 树时调用。首先调用父类的initState方法,然后初始化bgColor为colorList中的第一个颜色。接着,通过eventBus.on().listen方法,订阅事件总线上的BusNotificationTest事件。当接收到该事件时,会执行回调函数,在回调函数中,通过setState方法更新bgColor为colorList中对应索引的颜色。这里的event.index就是父组件触发事件时传递过来的颜色索引。
- dispose:当组件从 Widget 树中移除时调用。在这个方法中,调用eventBusExample.cancel()取消对事件总线的订阅,防止内存泄漏,然后调用父类的dispose方法。
- 构建 UI:
- 在build方法中,子组件构建了一个SizedBox,其宽度为屏幕宽度,高度为屏幕高度的一半。在SizedBox内部是一个Container,其背景颜色由bgColor决定。当bgColor因接收到事件通知而改变时,Container的背景颜色也会相应改变,从而实现了根据父组件通知动态更新子组件 UI 的效果。
3. 总结
通过上述代码,我们清晰地看到了如何在 Flutter 中利用事件总线实现父子组件之间的通信。父组件通过触发事件并携带相关数据,子组件通过订阅事件总线并根据接收到的事件数据更新自身状态和 UI。
这种方式有效地解耦了父子组件之间的直接依赖关系,提高了代码的可维护性和扩展性。在实际项目中,当存在多个组件之间复杂的交互时,事件总线是一种非常强大且灵活的解决方案。
本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~
往期文章
- flutter-使用extended_image操作图片的加载和状态处理以及缓存和下载
- flutter-制作可缩放底部弹出抽屉评论区效果
- flutter-实现Tabs吸顶的PageView效果
- Vue2全家桶+Element搭建的PC端在线音乐网站
- 助你上手Vue3全家桶之Vue3教程
- 助你上手Vue3全家桶之VueX4教程
- 助你上手Vue3全家桶之Vue-Router4教程
- 超详细!Vue的九种通信方式
- 超详细!Vuex手把手教程
- 使用nvm管理node.js版本以及更换npm淘宝镜像源
- vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
个人主页