flutter-使用EventBus实现组件间数据通信

1. 效果预览

在 Flutter 应用开发中,组件间的通信是一个常见且重要的需求。当涉及到父子组件之间复杂的交互时,使用事件总线(Event Bus)可以有效地实现解耦和灵活的消息传递。本文将通过一段具体的代码,详细介绍如何在 Flutter 中利用事件总线实现父子组件之间的通信。

2. 安装插件

yaml 复制代码
event_bus: ^2.0.0

创建eventBus.dart文件,写入以下内容:

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

EventBus eventBus = EventBus();

/// 通知测试
class BusNotificationTest {
  int index;
  BusNotificationTest(this.index);
}

3. 结构分析

这段代码展示了如何在 Flutter 中通过事件总线实现父子组件之间的通信,具体功能为:在父组件EventBusParentPage中,用户点击按钮后,会触发一个通知事件,子组件EventBusChildPage监听该事件,并根据事件携带的信息改变自身的背景颜色。

  1. 父组件:EventBusParentPage
dart 复制代码
/// 事件Bus通知父类
class EventBusParentPage extends StatefulWidget {
  const EventBusParentPage({super.key});

  @override
  EventBusParentPageState createState() => EventBusParentPageState();
}

class EventBusParentPageState extends State<EventBusParentPage> {
  /// 颜色索引
  int index = 0;

  /// 通知变色
  void handleColorChange() {
    index++;
    if (index > 2) {
      index = 0;
    }
    eventBus.fire(BusNotificationTest(index));
  }

  @override
  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关键字创建,意味着它是一个不可变的组件实例。
  1. 子组件:EventBusChildPage
dart 复制代码
/// 事件Bus通知子类
class EventBusChildPage extends StatefulWidget {
  const EventBusChildPage({super.key});

  @override
  EventBusChildPageState createState() => EventBusChildPageState();
}

class EventBusChildPageState extends State<EventBusChildPage> {
  /// 颜色列表
  List<Color> colorList = [Colors.red, Colors.yellow, Colors.blue];

  /// 刷新监听
  late StreamSubscription<BusNotificationTest> eventBusExample;

  /// 背景颜色
  late Color bgColor;

  @override
  void initState() {
    super.initState();
    bgColor = colorList[0];
    // 监听颜色索引变化
    eventBusExample = eventBus.on<BusNotificationTest>().listen((event) {
      setState(() {
        bgColor = colorList[event.index];
      });
    });
  }

  @override
  void dispose() {
    eventBusExample.cancel();
    super.dispose();
  }

  @override
  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。

这种方式有效地解耦了父子组件之间的直接依赖关系,提高了代码的可维护性和扩展性。在实际项目中,当存在多个组件之间复杂的交互时,事件总线是一种非常强大且灵活的解决方案。


本次分享就到这儿啦,我是鹏多多,深耕前端的技术创作者,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

PS:在本页按F12,在console中输入document.getElementsByClassName('panel-btn')[0].click();有惊喜哦~

往期文章

相关推荐
UpgradeLink2 小时前
Electron项目使用electron-updater与UpgradeLink接入参考
开发语言·前端·javascript·笔记·electron·用户运营
小白的程序空间2 小时前
通俗易懂理解Flutter架构
flutter·架构
程序员祥云2 小时前
技能特⻓回答
前端·面试
xiaoxue..2 小时前
React 新手村通关指南:状态、组件与魔法 UI
前端·javascript·react.js·ui
狮恒2 小时前
OpenHarmony Flutter 分布式数据持久化:跨设备数据一致性与同步方案
分布式·flutter·wpf·openharmony
晚霞的不甘2 小时前
Flutter + OpenHarmony 国际化与无障碍(i18n & a11y)深度实践:打造真正包容的鸿蒙应用
flutter·华为·harmonyos
晚霞的不甘2 小时前
Flutter + OpenHarmony 架构演进:从单体到模块化、微前端与动态能力的现代化应用体系
前端·flutter·架构
代码or搬砖2 小时前
Vue生命周期总结(四个阶段,八个钩子函数)
前端·javascript·vue.js
梵尔纳多3 小时前
第一个 Electron 程序
前端·javascript·electron