Flutter数据流继承插件inherited_stream的使用

Flutter数据流继承插件inherited_stream的使用

概述

inherited_stream 是一个用于在 Flutter 中管理数据流(Stream)的插件。它通过继承 InheritedWidget 来实现对 Stream 的监听,并在 Stream 发射新值时自动更新其依赖的子部件。

插件功能

  • 动态更新:当 Stream 发射新值时,所有依赖该 Stream 的子部件会自动重新构建。
  • 简化状态管理:无需手动管理状态,只需将 Stream 注入到 InheritedStream 中即可。

使用步骤

1. 创建一个 InheritedStream

首先,我们需要创建一个继承自 InheritedStream 的类,用于包装我们的 Stream

// 这里我们使用 ValueStream 来管理一个 double 类型的进度值
class ProgressModel extends InheritedStream<ValueStream<double>> {
  const ProgressModel({
    Key key,
    ValueStream<double> stream,
    Widget child,
  }) : super(key: key, stream: stream, child: child);

  // 提供一个静态方法来获取当前的进度值
  static double of(BuildContext context) {
    return context
        .dependOnInheritedWidgetOfExactType<ProgressModel>()
        .stream
        .value;
  }
}

2. 将 InheritedStream 插入到 Widget 树中

在应用中,我们需要将 ProgressModel 插入到 Widget 树中,并为其提供一个 Stream

class _MyState extends State<MyPage> {
  final _subject = BehaviorSubject<double>.seeded(0.0); // 创建一个初始值为 0.0 的行为流

  [@override](/user/override)
  void dispose() {
    _subject.close(); // 关闭流以释放资源
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: ProgressModel(
        stream: _subject.stream, // 将行为流注入到 ProgressModel 中
        child: Progress(), // 渲染进度条
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _subject.add(Random.nextDouble()), // 随机增加进度
      ),
    );
  }
}

3. 在子部件中注册依赖

在需要监听 Stream 的子部件中,我们可以使用 ProgressModel.of(context) 来获取当前的进度值,并根据该值渲染 UI。

class Progress extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 获取当前进度值
    final progress = ProgressModel.of(context);
    final percentage = (progress * 100).toStringAsFixed(2); // 计算百分比

    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        // 渲染圆形进度条
        CircularProgressIndicator(
          value: progress,
          strokeWidth: 8,
        ),
        const SizedBox(height: 16),
        // 显示百分比文本
        Text('$percentage%', style: Theme.of(context).textTheme.headline6),
      ],
    );
  }
}

完整示例代码

以下是一个完整的示例代码,展示了如何使用 inherited_stream 插件来管理数据流并更新 UI。

import 'dart:math' show Random;
import 'package:flutter/material.dart';
import 'package:inherited_stream/inherited_stream.dart';
import 'package:rxdart/rxdart.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(home: HomePage());
  }
}

class HomePage extends StatefulWidget {
  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  final _subject = BehaviorSubject<double>.seeded(0.0);

  [@override](/user/override)
  void dispose() {
    _subject.close();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8),
        child: Center(
          child: ProgressModel(stream: _subject.stream, child: Progress()),
        ),
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          FloatingActionButton(
            child: const Icon(Icons.add),
            onPressed: () {
              final random = (Random().nextDouble() * 0.1);
              final value = _subject.value + random >= 1.0
                  ? 1.0
                  : _subject.value + random;
              _subject.add(value);
            },
          ),
          const SizedBox(height: 8),
          FloatingActionButton(
            child: const Icon(Icons.clear),
            onPressed: () => _subject.add(0),
          ),
        ],
      ),
    );
  }
}

class Progress extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final progress = ProgressModel.of(context);
    final percentage = (progress * 100).toStringAsFixed(2);
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        CircularProgressIndicator(value: progress, strokeWidth: 8),
        const SizedBox(height: 16),
        Text('$percentage%', style: Theme.of(context).textTheme.headline6),
      ],
    );
  }
}

class ProgressModel extends InheritedStream<ValueStream<double>> {
  const ProgressModel({
    Key key,
    ValueStream<double> stream,
    Widget child,
  }) : super(key: key, stream: stream, child: child);

  static double of(BuildContext context) {
    return context
        .dependOnInheritedWidgetOfExactType<ProgressModel>()
        .stream
        .value;
  }
}

更多关于Flutter数据流继承插件inherited_stream的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据流继承插件inherited_stream的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


inherited_stream 是一个用于在 Flutter 中管理数据流的插件,它结合了 InheritedWidgetStream 的优势,使得在 Flutter 应用中更方便地管理和传递数据流。通过 inherited_stream,你可以在 widget 树中轻松地共享和订阅数据流,而不需要手动管理 StreamSubscription

安装

首先,你需要在 pubspec.yaml 文件中添加 inherited_stream 依赖:

dependencies:
  flutter:
    sdk: flutter
  inherited_stream: ^1.0.0

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

基本用法

1. 创建 InheritedStream

InheritedStream 是一个 InheritedWidget,它包装了一个 Stream,并允许在 widget 树中共享这个 Stream

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

class MyInheritedStream extends InheritedStream<int> {
  MyInheritedStream({
    Key? key,
    required Stream<int> stream,
    required Widget child,
  }) : super(key: key, stream: stream, child: child);

  [@override](/user/override)
  bool updateShouldNotify(MyInheritedStream oldWidget) {
    return oldWidget.stream != stream;
  }
}

2. 使用 InheritedStream

你可以在 widget 树中使用 MyInheritedStream 来共享数据流。子 widget 可以通过 InheritedStream.of(context) 来访问这个数据流。

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 创建一个简单的 Stream,每秒递增一个整数
    final stream = Stream.periodic(Duration(seconds: 1), (i) => i);

    return MaterialApp(
      home: MyInheritedStream(
        stream: stream,
        child: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 获取 InheritedStream 中的数据流
    final stream = MyInheritedStream.of(context).stream;

    return Scaffold(
      appBar: AppBar(
        title: Text('InheritedStream Example'),
      ),
      body: Center(
        child: StreamBuilder<int>(
          stream: stream,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Text('Count: ${snapshot.data}');
            } else {
              return Text('Waiting for data...');
            }
          },
        ),
      ),
    );
  }
}
回到顶部