什么是Streams?
streams就好比传送带,将物品放到一侧,他将自动运送到另一侧。我们可以将数据对象放在传送带上,他会被传送带传输。如果传送带不是无限长的(它不是一个无限的流, 例如rxjs里的interval,如果不取消订阅,他会随着时间一直流动),那么传送带的物品终会掉落。
为了避免传送带上的物品无辜掉落,我们可以做一些事情,使得物品在掉落之前实现某些价值。
Dart Streams 和 Rx
Rx里面的可观察对象命名未Observable,它与Dart Streams里的Stream是同等的意义,所以在可以使用Stream的任何地方赋予Observable的含义
listen / subscribe, 进行序列订阅,同等意义
listen()返回一个StreamSubscription对象,调用cancel()释放订阅
StreamController / Subject, 发布值,相当于在传送带的左侧添加物品,同等意义
使用StreamBuilder
不用使用initState()和setState(),flutter提供了一个方便的widget称之为StreamBuilder,它需要一个Stream和一个builder函数,只要Stream发出一个新值就会调用他,不再需要initState或dispose.
1 | body: Center( |
相对于直接订阅,使用StreamBuilder有几个明显的区别:
- setState()在listen()时接受新值时会重建整页,而StreamBuilder只会重建他自己的widget
- snappShot包含从Stream接收的最新数据
- 含有一个initialData,用于第一次构建,即屏幕的第一帧,解决StreamBuilder不能在第一帧期间接收值的问题,如果snappShot无效,则返回默认Widget,适用于某些业务场景
flutter中使用BLOC模式
什么是bloc模式?
bloc[Business Logic Component]翻译过来就是业务逻辑组件,把业务逻辑抽出来,数据和ui解耦,一处改动,多处更新
上面描述的是组件的一些基本行为,【展示数据】,【发送事件】,flutter中实现Bloc的精髓就是stream,严格遵守了单一职责原则,代码解耦更好。
UI1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
...
}
class CounterPage extends StateLessWidget {
@override
Widget build(BuildContext context) {
final IncrementBloc bloc = BlocProvider.of<IncrementBloc>(context);
return Scaffod(
appBar: AppBar(
title: Text('block')
),
body: Center(
child: StreamBuilder<int>(
stream: bloc._counterStream,
initialData: 0,
builder: (BuildContext context, AsyncSnapShot<int> snapshot) {
return Text('clicked ${snapshot.data} times')
}
)
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
bloc._actionSink.add(null); // 发送事件
}
)
)
}
}
Bloc
1 | class IncrementBloc { |