Flutter响应式编程插件rxdart的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter响应式编程插件rxdart的使用

RxDart简介

RxDart 是一个扩展 Dart 的 StreamsStreamControllers 功能的库。它并不提供 Observable 类来替代 Dart Streams,而是提供了额外的 Stream 类、操作符(Stream 类的扩展方法)和 Subjects。

如何使用RxDart

示例:读取Konami代码

import 'package:rxdart/rxdart.dart';

void main() {
  const konamiKeyCodes = <int>[
    KeyCode.UP,
    KeyCode.UP,
    KeyCode.DOWN,
    KeyCode.DOWN,
    KeyCode.LEFT,
    KeyCode.RIGHT,
    KeyCode.LEFT,
    KeyCode.RIGHT,
    KeyCode.B,
    KeyCode.A,
  ];

  final result = querySelector('#result')!;

  document.onKeyUp
      .map((event) => event.keyCode)
      .bufferCount(10, 1) // An extension method provided by rxdart
      .where((lastTenKeyCodes) => const IterableEquality<int>().equals(lastTenKeyCodes, konamiKeyCodes))
      .listen((_) => result.innerHtml = 'KONAMI!');
}

API概述

RxDart通过三种方式为Dart Streams添加功能:

  • Stream Classes - 创建具有特定功能的流,如合并多个流。
  • Extension Methods - 将源流转换为具有不同功能的新流,例如缓冲或节流事件。
  • Subjects - 具有额外功能的StreamControllers。

Stream Classes

RxDart提供了许多用于创建特定类型流的类,例如:

  • CombineLatestStream / Rx.combineLatest2...Rx.combineLatest9
  • ConcatStream / Rx.concat
  • MergeStream / Rx.merge

Extension Methods

RxDart提供的扩展方法可以用于任何 Stream。它们将源流转换为具有附加功能的新流,例如缓冲或节流事件。例如:

Stream.fromIterable([1, 2, 3])
  .throttleTime(Duration(seconds: 1))
  .listen(print); // prints 1

Subjects

RxDart 提供了两种带有额外功能的 StreamControllers:

  • BehaviorSubject - 缓存最新添加的值或错误,并在新监听器订阅时发出该值或错误。
  • ReplaySubject - 缓存所有添加的值,并在新监听器订阅时发出这些值。

Rx Observables vs Dart Streams

虽然在许多情况下,Streams 和 Observables 工作方式相同,但如果你熟悉标准的 Rx Observables,Stream API 的某些特性可能会让你感到意外。以下表格展示了两者之间的区别:

情况 Rx Observables Dart Streams
错误抛出 Observable 终止并抛出错误 错误被发出且流继续
冷 Observable 多个订阅者可以监听同一个冷 Observable,每个订阅会收到唯一的数据流 只有一个订阅者
热 Observable 是,称为广播流
{Publish, Behavior, Replay}Subject 是否是热的
Single/Maybe/Completable 是,使用 rxdart_ext Single
支持背压
是否可以发出 null 是,除了 RxJava
默认同步
是否可以暂停/恢复订阅

示例代码

Flutter中的简单计数器应用示例

以下是一个简单的Flutter应用程序示例,演示如何使用RxDart进行状态管理。

1. 添加依赖

首先,在你的 pubspec.yaml 文件中添加 rxdart 依赖:

dependencies:
  flutter:
    sdk: flutter
  rxdart: ^0.27.0

2. 创建主文件 main.dart

import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  final BehaviorSubject<int> _counterSubject = BehaviorSubject<int>.seeded(0);
  int get _counter => _counterSubject.value;

  void _incrementCounter() {
    _counterSubject.add(_counter + 1);
  }

  @override
  void dispose() {
    _counterSubject.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            StreamBuilder<int>(
              stream: _counterSubject.stream,
              initialData: _counter,
              builder: (context, snapshot) {
                return Text(
                  '${snapshot.data}',
                  style: Theme.of(context).textTheme.headline4,
                );
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

这个示例展示了如何使用 BehaviorSubject 来管理计数器的状态,并通过 StreamBuilder 在UI中显示计数器的值。每当用户点击浮动按钮时,计数器的值会增加并在UI上更新。

希望这个详细的指南能帮助你更好地理解和使用RxDart!如果你有任何问题或需要进一步的帮助,请随时提问。


更多关于Flutter响应式编程插件rxdart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter响应式编程插件rxdart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,rxdart 是一个流行的响应式编程库,它基于 Dart 的 streamsRx(Reactive Extensions)概念,提供了强大的工具来处理异步数据流。以下是一个简单的示例,展示了如何在 Flutter 应用中使用 rxdart 来实现响应式编程。

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

dependencies:
  flutter:
    sdk: flutter
  rxdart: ^0.26.0  # 请根据需要检查最新版本号

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

接下来,我们创建一个 Flutter 应用,演示如何使用 rxdartBehaviorSubjectmap 操作符来处理数据。

1. 创建一个 Dart 文件来处理数据流逻辑

创建一个名为 data_stream.dart 的文件,并添加以下代码:

import 'package:rxdart/rxdart.dart';

class DataStream {
  // 创建一个 BehaviorSubject,它可以在订阅后立即获取最新的值
  private final BehaviorSubject<String> _subject = BehaviorSubject<String>();

  // 获取 Observable 流
  Observable<String> get dataStream => _subject.asObservable();

  // 发送数据到流中
  void sendData(String data) {
    _subject.sink.add(data);
  }

  // 关闭流
  void dispose() {
    _subject.close();
  }
}

2. 在 Flutter Widget 中使用数据流

在你的主 dart 文件(例如 main.dart)中,使用上面定义的 DataStream 类来处理数据,并展示在 UI 上。

import 'package:flutter/material.dart';
import 'data_stream.dart';

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

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

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final DataStream _dataStream = DataStream();
  String _currentData = '';

  @override
  void initState() {
    super.initState();

    // 订阅数据流并更新 UI
    _subscriptions = _dataStream.dataStream
      .map((data) => "Received: $data")  // 对数据进行处理
      .listen((newData) {
        setState(() {
          _currentData = newData;
        });
      });
  }

  @override
  void dispose() {
    _dataStream.dispose();  // 清理资源
    _subscriptions.cancel();  // 取消订阅
    super.dispose();
  }

  var _subscriptions;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter RxDart Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              _currentData,
              style: TextStyle(fontSize: 24),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                _dataStream.sendData("Hello, RxDart!");
              },
              child: Text('Send Data'),
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. DataStream 类

    • 使用 BehaviorSubject 来创建一个可以立即获取最新值的流。
    • 提供一个方法来发送数据到流中 (sendData)。
    • 提供一个方法来获取流 (dataStream)。
    • 提供一个方法来关闭流 (dispose)。
  2. MyHomePage 类

    • 创建一个 DataStream 实例。
    • initState 方法中订阅 dataStream,并使用 map 操作符来处理数据。
    • 使用 listen 方法来监听流中的新数据,并在数据更新时调用 setState 来更新 UI。
    • dispose 方法中取消订阅并清理资源。
  3. UI

    • 显示当前接收到的数据。
    • 提供一个按钮来发送数据到流中。

这个示例展示了如何使用 rxdart 库在 Flutter 应用中实现基本的响应式编程。你可以根据需要扩展这个示例,添加更多的操作符和逻辑来处理更复杂的数据流。

回到顶部