1.说明
无意间发现了一个好用的库rxdart
,它为 Dart 的 Stream
添加了额外的功能。
2.功能
(1)合并多个流Stream
借助Rx.combineLatest2()
合并两个流stream1和stream2
。
注意:如果dart文件中同时使用了getx
,需要隐藏掉Rx,否则会冲突。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
// import 'package:get/get.dart' hide Rx;
// Library: rxdart , v0.28.0
// 为 Dart 的 Stream 添加了额外的功能
// 合并多个流 CombineLatestStream
// Publisher: fluttercommunity.dev
class RxdartDemo extends StatefulWidget {
const RxdartDemo({super.key});
State<RxdartDemo> createState() => _RxdartDemoState();
}
class _RxdartDemoState extends State<RxdartDemo> {
//(热重载报错) Unhandled Exception: Bad state: Stream has already been listened to.
// 解决:更改为广播流(broadcast)。
StreamController<String> streamController1 = StreamController<String>.broadcast();
late Stream<String> stream1;
StreamController<int> streamController2 = StreamController<int>.broadcast();
late Stream<int> stream2;
StreamController<List<int>> streamController3 = StreamController<List<int>>.broadcast();
late Stream<List<int>> stream3;
void initState() {
super.initState();
stream1 = streamController1.stream;
streamController1.add("A");
stream2 = streamController2.stream;
streamController2.add(1);
stream3 = streamController3.stream;
streamController3.add([1, 2]);
}
void dispose() {
streamController1.close();
streamController2.close();
streamController3.close();
super.dispose();
}
// Rx.combineLatest2 将两个Stream流合并
Stream<String> get streamCombined =>
Rx.combineLatest2(stream1, stream2, (a, b) => '$a - $b');
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"单个流Stream",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 12,
),
StreamBuilder<List<int>>(
stream: stream3,
builder: (context, snapshot) {
return Text(
"${snapshot.data}",
style: const TextStyle(fontSize: 16),
);
}),
const SizedBox(
height: 12,
),
const Text(
"合并多个流Stream",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(
height: 12,
),
StreamBuilder<String>(
stream: streamCombined,
builder: (context, snapshot) {
return Text(
snapshot.data ?? 'empty',
style: const TextStyle(fontSize: 16),
);
}),
TextButton(
onPressed: () {
streamController1.add("b");
streamController2.add(2);
streamController3.add([3, 4]);
},
child: const Text(
'Change',
style: TextStyle(fontSize: 16, color: Colors.blue),
))
],
),
),
);
}
}