Flutter 如何在Flatter Streambuilder中重新启动流?
我有一个简单的流,它在执行操作时返回倒计时Flutter 如何在Flatter Streambuilder中重新启动流?,flutter,stream-builder,Flutter,Stream Builder,我有一个简单的流,它在执行操作时返回倒计时 static Stream<double> counterStream = (() async* { double i = 0.1; double z = 0.0; while (z < 0.99) { await Future.delayed(Duration(seconds: 1)); yield z = z+i; } })(); 第一次流正确运行,但第二次没有启动,如果我关闭屏幕并再次返回,启动流-我得到一个错误 错
static Stream<double> counterStream = (() async* {
double i = 0.1;
double z = 0.0;
while (z < 0.99) {
await Future.delayed(Duration(seconds: 1));
yield z = z+i;
}
})();
第一次流正确运行,但第二次没有启动,如果我关闭屏幕并再次返回,启动流-我得到一个错误
错误状态:流已被侦听
我不知道如何通过单击按钮重新加载已完成执行且理论上状态为ConnectionState.done
的流
全类代码
class UpdatePage extends StatefulWidget {
UpdatePage({Key key, this.title}) : super(key: key);
static const String routeName = "/UpdatePage";
final String title;
@override
_UpdatePageState createState() => new _UpdatePageState();
}
class _UpdatePageState extends State<UpdatePage> {
Stream<double> _result;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(""),
),
body: SafeArea(
child: StreamBuilder<double>(
stream: _result,
builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
List<Widget> children;
if (snapshot.hasError) {
children = <Widget>[
Center(
child: Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
)
];
} else {
switch (snapshot.connectionState) {
case ConnectionState.none:
children = <Widget>[
Center(child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Text("Обновление данных", style: new TextStyle( fontSize: 18.0))),
)),
Center(
child: Container(padding: EdgeInsets.all(20.0),child: RaisedButton.icon(
textColor: Colors.white,
icon: FaIcon(FontAwesomeIcons.retweet, size: 18,),
color: Color(0xFF6200EE), label: Text("Обновить"),
onPressed: () {
setState(() {
_result = DatabaseAccess.counterStream;
});
},
),),
),
];
break;
case ConnectionState.waiting:
children = <Widget>[
Center(
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
),
),
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
center: new Text('', style: new TextStyle( fontSize: 20.0)),
),
];
break;
case ConnectionState.active:
children = <Widget>[
Center(
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
),
),
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
percent: snapshot.data,
center: new Text('${snapshot.data.toStringAsFixed(2)}', style: new TextStyle( fontSize: 20.0)),
progressColor: Colors.orange,
),
];
break;
case ConnectionState.done:
children = <Widget>[
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
center: new Icon(
Icons.done,
size: MediaQuery.of(context).size.width/4,
color: Colors.green,
),
backgroundColor: Colors.grey,
progressColor: Colors.orange,
)
,
Center(child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Text("Обновление успешно завершено", style: new TextStyle( fontSize: 18.0))),
)),
Center(
child: Container(padding: EdgeInsets.all(20.0),child: RaisedButton.icon(
textColor: Colors.white,
icon: FaIcon(FontAwesomeIcons.retweet, size: 18,),
color: Color(0xFF6200EE), label: Text("Обновить"),
onPressed: () {
setState(() {
_result = DatabaseAccess.counterStream;
});
},
),),
),
];
break;
}
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
);
},
)
));
;
class UpdatePage扩展StatefulWidget{
UpdatePage({Key-Key,this.title}):super(Key:Key);
静态常量字符串routeName=“/UpdatePage”;
最后的字符串标题;
@凌驾
_UpdatePageState createState()=>new_UpdatePageState();
}
类_UpdatePageState扩展状态{
流结果;
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(“”),
),
正文:安全区(
孩子:StreamBuilder(
流:_结果,
生成器:(BuildContext上下文,异步快照){
列出儿童名单;
if(snapshot.hasError){
儿童=[
居中(
子:图标(
Icons.error\u轮廓,
颜色:颜色,红色,
尺码:60,
),
),
填充物(
填充:仅限常量边集(顶部:16),
子项:Text('Error:${snapshot.Error}'),
)
];
}否则{
交换机(快照.连接状态){
案例连接状态。无:
儿童=[
中心(子:填充)(
填充:常数边集全部(8.0),
子:容器(子:文本(“ббббббббх”,样式:新文本样式(fontSize:18.0)),
)),
居中(
子:容器(填充:EdgeInsets.all(20.0),子:RaisedButton.icon(
textColor:Colors.white,
图标:FaIcon(fontaweomeicons.retweet,大小:18,),
颜色:颜色(0xFF6200EE),标签:文本,
已按下:(){
设置状态(){
_结果=DatabaseAccess.counterStream;
});
},
),),
),
];
打破
案例连接状态。正在等待:
儿童=[
居中(
孩子:新的填充物(
填充:边缘组。对称(水平:10.0),
),
),
新型循环指示器(
半径:MediaQuery.of(context).size.width/2,
线宽:4.0,
居中:新文本(“”,样式:新文本样式(fontSize:20.0)),
),
];
打破
案例连接状态.active:
儿童=[
居中(
孩子:新的填充物(
填充:边缘组。对称(水平:10.0),
),
),
新型循环指示器(
半径:MediaQuery.of(context).size.width/2,
线宽:4.0,
百分比:snapshot.data,
中心:新文本(“${snapshot.data.toStringAsFixed(2)}”,样式:新文本样式(fontSize:20.0)),
progressColor:Colors.orange,
),
];
打破
案例连接状态。完成:
儿童=[
新型循环指示器(
半径:MediaQuery.of(context).size.width/2,
线宽:4.0,
中心:新图标(
完成了,
size:MediaQuery.of(context).size.width/4,
颜色:颜色。绿色,
),
背景颜色:颜色。灰色,
progressColor:Colors.orange,
)
,
中心(子:填充)(
填充:常数边集全部(8.0),
子:容器(子:文本(“бббббббббббббббббббб,
)),
居中(
子:容器(填充:EdgeInsets.all(20.0),子:RaisedButton.icon(
textColor:Colors.white,
图标:FaIcon(fontaweomeicons.retweet,大小:18,),
颜色:颜色(0xFF6200EE),标签:文本,
已按下:(){
设置状态(){
_结果=DatabaseAccess.counterStream;
});
},
),),
),
];
打破
}
}
返回列(
mainAxisAlignment:mainAxisAlignment.center,
crossAxisAlignment:crossAxisAlignment.center,
儿童:儿童,,
);
},
)
));
;
}
}由于
counterStream
是静态的,因此在应用程序的生命周期内初始化一次。在初始化过程中,async*
函数只调用一次
因此,在应用程序的生命周期内只创建一个流<代码>逆流是一个参考
class UpdatePage extends StatefulWidget {
UpdatePage({Key key, this.title}) : super(key: key);
static const String routeName = "/UpdatePage";
final String title;
@override
_UpdatePageState createState() => new _UpdatePageState();
}
class _UpdatePageState extends State<UpdatePage> {
Stream<double> _result;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(""),
),
body: SafeArea(
child: StreamBuilder<double>(
stream: _result,
builder: (BuildContext context, AsyncSnapshot<double> snapshot) {
List<Widget> children;
if (snapshot.hasError) {
children = <Widget>[
Center(
child: Icon(
Icons.error_outline,
color: Colors.red,
size: 60,
),
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'),
)
];
} else {
switch (snapshot.connectionState) {
case ConnectionState.none:
children = <Widget>[
Center(child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Text("Обновление данных", style: new TextStyle( fontSize: 18.0))),
)),
Center(
child: Container(padding: EdgeInsets.all(20.0),child: RaisedButton.icon(
textColor: Colors.white,
icon: FaIcon(FontAwesomeIcons.retweet, size: 18,),
color: Color(0xFF6200EE), label: Text("Обновить"),
onPressed: () {
setState(() {
_result = DatabaseAccess.counterStream;
});
},
),),
),
];
break;
case ConnectionState.waiting:
children = <Widget>[
Center(
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
),
),
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
center: new Text('', style: new TextStyle( fontSize: 20.0)),
),
];
break;
case ConnectionState.active:
children = <Widget>[
Center(
child: new Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
),
),
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
percent: snapshot.data,
center: new Text('${snapshot.data.toStringAsFixed(2)}', style: new TextStyle( fontSize: 20.0)),
progressColor: Colors.orange,
),
];
break;
case ConnectionState.done:
children = <Widget>[
new CircularPercentIndicator(
radius: MediaQuery.of(context).size.width/2,
lineWidth: 4.0,
center: new Icon(
Icons.done,
size: MediaQuery.of(context).size.width/4,
color: Colors.green,
),
backgroundColor: Colors.grey,
progressColor: Colors.orange,
)
,
Center(child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(child: Text("Обновление успешно завершено", style: new TextStyle( fontSize: 18.0))),
)),
Center(
child: Container(padding: EdgeInsets.all(20.0),child: RaisedButton.icon(
textColor: Colors.white,
icon: FaIcon(FontAwesomeIcons.retweet, size: 18,),
color: Color(0xFF6200EE), label: Text("Обновить"),
onPressed: () {
setState(() {
_result = DatabaseAccess.counterStream;
});
},
),),
),
];
break;
}
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
);
},
)
));
;
static Stream<double> Function() counterStream = () async* {
double i = 0.1;
double z = 0.0;
while (z < 0.99) {
await Future.delayed(Duration(seconds: 1));
yield z = z+i;
}
};
onPressed: () {
setState(() {
_result = DatabaseAccess.counterStream();
});},