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();有惊喜哦~

往期文章

相关推荐
To_OC2 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic2 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy2 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志3 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble4 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯5 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜5 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
心中有国也有家6 小时前
AtomGit Flutter 鸿蒙客户端:ModalBottomSheet 实战
android·javascript·学习·flutter·华为·harmonyos
江华森6 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http