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
更多关于Flutter数据流继承插件inherited_stream的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
inherited_stream
是一个用于在 Flutter 中管理数据流的插件,它结合了 InheritedWidget
和 Stream
的优势,使得在 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...');
}
},
),
),
);
}
}