Flutter主题事件监听插件topic_events的使用

Flutter主题事件监听插件topic_events的使用

简介

本包通过提供一组组件帮助构建事件驱动系统:

  • 传输(Transport)
  • 代理(Broker)
  • 管理器(Manager)
  • 事件(Event)

这些组件设计为完全模块化且易于集成,可以组合以创建任意形状和复杂度的拓扑结构。它们可以通过静态或动态配置在运行时进行设置。

双向通信在传输和管理器之间得到支持。

示例拓扑

架构

API概览

class TopicEvent {
  String topic; // 标识符
  String cmd;
  dynamic payload;
}

abstract class TopicManager {
  String get topic; // 事件目标
  handleEvent(TopicEvent); // 消费传入的事件
  sendEvent(TopicEvent); // 产生传出的事件
}

abstract class TopicEventTransport {
  onReceive(TopicEvent); // 转发到代理
  onSend(TopicEvent); // 从代理接收
}

class TopicEventBroker {
  addManager(TopicManager);
  setTransport(TopicEventTransport);
}

使用

设置传输

class MySocket extends TopicEventTransport {
  void connect() =>
      // 自定义事件源(同步或异步)
      // 调用 *onReceive* 将传入的事件转发给代理
      myEventStream.listen(onReceive);

  // 必须覆盖此方法以处理传出的事件
  [@override](/user/override)
  void onSend(TopicEvent event) => myEventSink.add(event);
}

定义一个或多个管理器

class MyManager extends TopicManager {
  // 覆盖此方法以设置主题标识符
  [@override](/user/override)
  Topic get topic => 'my_topic';

  // 覆盖此方法以处理传入的事件
  [@override](/user/override)
  void handleEvent(TopicEvent event) {
    // 对事件进行操作
    // 调用 *sendEvent* 触发传出的 my_topic 事件
    sendEvent('add', 'some data');
  }
}

将传输和管理器传递给代理

final socket = MySocket();

TopicEventBroker()
  // 添加所需的管理器数量
  // 添加已有主题的管理器将替换现有管理器
  ..addManager(MyManager())
  ..addManager(MyOtherManager())
  // 代理一次只能有一个传输
  // 另一方面,传输可以处理多个代理,广播传入的事件
  // 反复调用 *setTransport* 将替换现有传输并取消注册代理
  ..setTransport(socket);

socket.connect();
socket.myEvents.add(TopicEvent('my_topic', 'do', 'something')); // -> MyManager
socket.myEvents.add(TopicEvent('my_other_topic', 'show', '{"arbitrary": "data"}')); // -> MyOtherManager

完整示例代码

import 'dart:async';

import 'package:topic_events/topic_events.dart';

void main() {
  final socket = AnimalSocket();

  TopicEventBroker()
    ..addManager(CatManager())
    ..addManager(DogManager())
    ..setTransport(socket);

  socket.connect();
  socket.events
      .add(TopicEvent(topicCat, cmdSay, 'something')); // "meow something"
  socket.events
      .add(TopicEvent(topicDog, cmdSay, 'anything')); // "woof anything"
}

class AnimalSocket extends TopicEventTransport {
  final events = StreamController<TopicEvent>();

  void connect() => events.stream.listen(onReceive);

  [@override](/user/override)
  void onSend(TopicEvent event) {
    if (event.cmd == cmdPrint) print(event.payload);
  }
}

class CatManager extends TopicManager {
  [@override](/user/override)
  Topic get topic => topicCat;

  [@override](/user/override)
  void handleEvent(TopicEvent event) {
    if (event.cmd == cmdSay) {
      sendEvent(cmdPrint, 'meow ${event.payload}');
    }
  }
}

class DogManager extends TopicManager {
  [@override](/user/override)
  Topic get topic => topicDog;

  [@override](/user/override)
  void handleEvent(TopicEvent event) {
    if (event.cmd == cmdSay) {
      sendEvent(cmdPrint, 'woof ${event.payload}');
    }
  }
}

const topicCat = 'cat', topicDog = 'dog', cmdSay = 'say', cmdPrint = 'print';

更多关于Flutter主题事件监听插件topic_events的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter主题事件监听插件topic_events的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter中使用topic_events插件来实现主题事件监听的示例代码。topic_events插件允许你在Flutter应用中监听和发布主题相关的事件,这在实现动态主题切换时非常有用。

首先,确保你已经在pubspec.yaml文件中添加了topic_events依赖:

dependencies:
  flutter:
    sdk: flutter
  topic_events: ^最新版本号  # 请替换为实际最新版本号

然后,运行flutter pub get来安装依赖。

接下来,让我们编写一些代码来演示如何使用topic_events

1. 创建一个事件类

首先,定义一个用于主题切换的事件类。例如,我们可以创建一个简单的ThemeChangeEvent类:

import 'package:topic_events/topic_events.dart';

class ThemeChangeEvent extends Event {
  final bool isDarkMode;

  ThemeChangeEvent({required this.isDarkMode});
}

2. 发布主题切换事件

在你的应用中,当主题发生变化时,发布这个事件。例如,在一个按钮点击事件中:

import 'package:flutter/material.dart';
import 'package:topic_events/topic_events.dart';
import 'theme_change_event.dart';  // 导入你创建的ThemeChangeEvent类

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final EventBus eventBus = EventBus();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(eventBus: eventBus),
    );
  }
}

class MyHomePage extends StatefulWidget {
  final EventBus eventBus;

  MyHomePage({required this.eventBus});

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

class _MyHomePageState extends State<MyHomePage> {
  bool isDarkMode = false;

  void toggleTheme() {
    setState(() {
      isDarkMode = !isDarkMode;
      // 发布主题切换事件
      widget.eventBus.fire(ThemeChangeEvent(isDarkMode: isDarkMode));
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Theme Event Listener'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: toggleTheme,
          child: Text('Toggle Theme'),
        ),
      ),
    );
  }
}

3. 监听主题切换事件

现在,让我们创建一个监听器来监听主题切换事件,并根据事件更新应用的主题:

import 'package:flutter/material.dart';
import 'package:topic_events/topic_events.dart';
import 'theme_change_event.dart';  // 导入你创建的ThemeChangeEvent类

class ThemeListener extends StatefulWidget {
  final EventBus eventBus;

  ThemeListener({required this.eventBus});

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

class _ThemeListenerState extends State<ThemeListener> {
  bool isDarkMode = false;

  @override
  void initState() {
    super.initState();
    // 订阅主题切换事件
    widget.eventBus.on<ThemeChangeEvent>().listen((event) {
      setState(() {
        isDarkMode = event.isDarkMode;
      });
      // 在这里可以添加更多逻辑,比如保存主题设置到SharedPreferences等
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: isDarkMode
          ? ThemeData.dark()
          : ThemeData.light(),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Theme Listener'),
        ),
        body: Center(
          child: Text('Current Theme: ${isDarkMode ? 'Dark' : 'Light'}'),
        ),
      ),
    );
  }

  @override
  void dispose() {
    // 取消订阅事件,避免内存泄漏
    widget.eventBus.cancelAllSubscriptions();
    super.dispose();
  }
}

4. 将事件发布者和监听者结合

最后,你需要将事件发布者和监听者结合起来。在一个实际的应用中,你可能会将监听者作为一个独立的Widget嵌入到你的主应用中。为了简化示例,这里我们直接在MyApp中嵌入监听者:

void main() {
  final EventBus eventBus = EventBus();
  runApp(MyApp(eventBus: eventBus));
}

class MyApp extends StatelessWidget {
  final EventBus eventBus;

  MyApp({required this.eventBus});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Stack(
          children: [
            // 监听者
            ThemeListener(eventBus: eventBus),
            // 事件发布者
            Positioned(
              bottom: 20,
              right: 20,
              child: MyHomePage(eventBus: eventBus),
            ),
          ],
        ),
      ),
    );
  }
}

这个示例展示了如何使用topic_events插件在Flutter应用中实现主题事件的监听和发布。你可以根据实际需求进一步扩展和修改这个示例。

回到顶部