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

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监听该事件,并根据事件携带的信息改变自身的背景颜色。

  1. 父组件: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关键字创建,意味着它是一个不可变的组件实例。
  1. 子组件: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。

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


本次分享就到这儿啦,我是鹏多多,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

往期文章

个人主页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冲浪的鹏多多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值