Stream
虽然可以对事件进行发送,但是只能使用现有的数据进行发送,无法做到真正的一方制造,一方消费的方式,因此在此基础上出现了StreamContoller
,可以对其进行灵活的逻辑控制。StreamContoller
可以单独使用,也可以与StreamBuilder
配合使用。只是页面结束后记得移除事件通知,以防出现不必要的问题。
该操作在实际开发过程中可以使用在类似于购物车数量的加减变化上。做到灵活的数据解耦
以下是一个简单的示例,点击按键进行异步的数字更改。建议先运行代码看下效果。:
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
StreamController<int> streamController = StreamController<int>();//这个用于直接在StreamBuild中进行UI更新操作
StreamController<int> streamController2 = StreamController<int>(//这个可以对数据进行监听,但是一次只能有一个监听,所以不能在StreamBuild中进行使用
onListen: (){
//监听添加时候,触发该回调
print('YM---streamController2--->添加监听');
},
onCancel: (){
//监听撤销时候,触发该回调
print('YM--streamController2---->撤销');
},
onPause: (){
//监听暂停时候,触发该回调
print('YM---streamController2--->暂停');
},
onResume: (){
//监听重新执行时候,触发该回调
print('YM---streamController2--->重新执行');
}
);
StreamSubscription streamSubscription;
@override
void initState() {
super.initState();
streamSubscription = streamController2.stream.listen((event) {//监听只能创建一个
print('YM---->接收的事件:$event');
});
streamSubscription.onDone(() {
//监听重新执行时候,触发该回调
print('YM---streamController2--->流关闭');
});
streamSubscription.onError((error) {
//监听重新执行时候,触发该回调
print('YM---streamController2--->流错误');
});
}
@override
void dispose() {
super.dispose();
streamSubscription.cancel();
streamController.close();//关闭流
streamController2.close();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
home: Scaffold(
appBar: AppBar(
title: Text('Material App Bar'),
),
body: Column(
children: [
StreamBuilder<int>(
stream: streamController.stream,
builder: (BuildContext context, AsyncSnapshot<int> snapshot){
if(snapshot.hasError){
var error = snapshot.error;
print('YM------>error:$error');
}
switch(snapshot.connectionState){
case ConnectionState.none:
print('YM------>事件为none');
break;
case ConnectionState.waiting:
print('YM------>事件在等待执行中');
break;
case ConnectionState.active:
//Stream流中,每次发送数据都会在这里执行,如果Stream出现错误,这里依然可以收到内容,注意判空处理
int value = snapshot.data;
print('YM------>事件在活动中:值为:$value');
return Text('计数:$value');
break;
case ConnectionState.done:
print('YM------>事件结束');
break;
}
return Text('计数:');
},
),
RaisedButton(
onPressed: (){
streamController.sink.add(10);
},
child: Text('计数'),
),
RaisedButton(
onPressed: (){
streamController.sink.close();
},
child: Text('结束'),
),
RaisedButton(
onPressed: (){
streamController.addError(-99);
},
child: Text('错误'),
),
RaisedButton(
onPressed: (){
streamSubscription.cancel();
},
child: Text('撤销streamController2监听'),
),
RaisedButton(
onPressed: (){
streamSubscription.pause();
Future.delayed(Duration(seconds: 2),(){//暂停后发消息会保存起来,等下次启动再发
streamController2.sink.add(32);
});
},
child: Text('暂停streamController2监听'),
),
RaisedButton(
onPressed: (){
streamSubscription.resume();
},
child: Text('重新启动streamController2监听'),
),
],
),
),
);
}
}