Flutter事件总线插件flutter_bus的使用

Flutter事件总线插件flutter_bus的使用

FlutterBus 是一个用于 Flutter 应用的静态事件总线库。它由 Mindful Software 的 Michael Bushe 制作,灵感来源于广泛使用的 Swing EventBus。

这是 beta 版本的 API,可能会发生变化。虽然它简单小巧,但以下几点反馈尤其受欢迎:

  1. initialData 是否应该作为 FlutterBusBuilder 的属性?
    它看起来像 FutureBuilder,有时你希望有一个初始事件。然而,“向一个部件发布”违背了发布/订阅模式。

  2. on() 方法是否应返回 StreamSubscription
    它可能太泄露了,但暂停/恢复/取消显然是有用的。可以返回更小的接口。

  3. 主题(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 中。ThemeChangedEventCounterChangedEvent 是很好的例子。ThemeChangedEvent 是部件到部件的事件,封装了一个 UI API。CounterChangedEvent 是“业务逻辑”事件——对于计数器应用来说,业务就是改变计数器。

只有一个流处理所有事件类型,因此非常高效。

考虑为事件架构两个流和两个 EventBus:

  1. 使用 FlutterBus 来处理从部件到部件或 UI 服务到部件的事件。
  2. 使用 EventBusDart 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

1 回复

更多关于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. 接收事件

你可以通过订阅事件总线来接收事件。通常,你会在 StatefulWidgetinitState 方法中订阅,并在 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);
}
回到顶部