Flutter 如果网络请求失败,如何在流的基础上显示警报对话框
这是我到目前为止的代码。Flutter 如果网络请求失败,如何在流的基础上显示警报对话框,flutter,flutter-layout,bloc,Flutter,Flutter Layout,Bloc,这是我到目前为止的代码。 \u mBlock.mSpotStream是一个网络请求。 我感兴趣的是,如果\u mBlock.getSpots()由于网络错误而失败,同时将列表保留在屏幕上,如何显示警报对话框。我曾尝试将警报对话框作为小部件返回,但在这种情况下,我无法关闭它 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(Strings.o
\u mBlock.mSpotStream
是一个网络请求。
我感兴趣的是,如果\u mBlock.getSpots()
由于网络错误而失败,同时将列表保留在屏幕上,如何显示警报对话框。我曾尝试将警报对话框作为小部件返回,但在这种情况下,我无法关闭它
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(Strings.of(context).spot_list_title), centerTitle: true),
body: Container(
child: Column(
children: [
Expanded(
child: Stack(
children: [
StreamBuilder<List<SpotDto>>(
stream: _mBlock.mSpotStream,
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: () {
return _mBlock.getSpots();
},
child: ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, position) {
return SpotListItem(snapshot.data[position], () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(position.toString())));
});
},
),
);
},
),
Column(
children: [
Expanded(
child: StreamBuilder<Progress<bool>>(
stream: _mBlock.mStateStream,
builder: (context, snapshot) {
return Visibility(
visible: snapshot.data?.mIsLoading ?? false,
child: SizedBox.expand(
child: Container(
color: Colors.blue.withOpacity(Dimens.overlayOpacity),
child: Center(
child: CircularProgressIndicator(),
),
),
),
);
},
),
)
],
)
],
))
],
)),
);
}
}
showAlertDialog(BuildContext context, SpotListBlock block) {
StreamBuilder<Error<String>>(
stream: block.mErrorStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return AlertDialog(
title: Text(Strings.of(context).error),
content: Text(snapshot.data.mErrorMessage),
actions: [
FlatButton(
child: Text("Cancel"),
onPressed: () {
Navigator.pop(context, true);
},
)
],
);
} else {
return Row();
}
},
);
}
@覆盖
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:Text(Strings.of(context).spot\u list\u title),centerTitle:true),
主体:容器(
子:列(
儿童:[
扩大(
子:堆栈(
儿童:[
StreamBuilder(
流:_mBlock.mSpotStream,
生成器:(上下文,快照){
返回刷新指示器(
onRefresh:(){
返回_mBlock.getSpots();
},
子项:ListView.builder(
itemCount:snapshot.data?长度为0,
itemBuilder:(上下文、位置){
返回SpotListItem(快照.数据[位置],(){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(内容:Text(position.toString())));
});
},
),
);
},
),
纵队(
儿童:[
扩大(
孩子:StreamBuilder(
流:_mBlock.mStateStream,
生成器:(上下文,快照){
返回可见性(
可见:快照。数据?错误加载??错误,
子项:SizedBox.expand(
子:容器(
颜色:颜色。蓝色。带不透明度(尺寸。超容量),
儿童:中心(
子对象:CircularProgressIndicator(),
),
),
),
);
},
),
)
],
)
],
))
],
)),
);
}
}
showAlertDialog(BuildContext上下文,SpotListBlock){
StreamBuilder(
stream:block.mErrorStream,
生成器:(上下文,快照){
if(snapshot.hasData){
返回警报对话框(
标题:文本(Strings.of(context).error),
内容:文本(snapshot.data.mErrorMessage),
行动:[
扁平按钮(
子项:文本(“取消”),
已按下:(){
pop(上下文,true);
},
)
],
);
}否则{
返回行();
}
},
);
}
显示警报对话框只是一个简单的调用,例如:
await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: 'alert!!!',
content: 'hello world',
actions: [
FlatButton(child: Text('cancel'), onPressed: () => Navigator.pop(context, false)),
FlatButton(child: Text('ok'), onPressed: () => Navigator.pop(context, true)),
],
);
},
)
等待显示对话框(
上下文:上下文,
生成器:(BuildContext上下文){
返回警报对话框(
标题:“警惕!!!”,
内容:“你好,世界”,
行动:[
FlatButton(子项:Text('cancel'),按下时:()=>Navigator.pop(上下文,false)),
FlatButton(子项:Text('ok'),按下时:()=>Navigator.pop(上下文,true)),
],
);
},
)
当您调用
showDialog
时,屏幕上将显示一个对话框。最后,我这样修复了它,这是我能够修复此问题的唯一方法,任何评论都将不胜感激:
我的解决方案就是基于这个要点
类SpotListScreen扩展了无状态小部件{
最终SpotListBlock_mBlock=SpotListBlock();
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(标题:Text(Strings.of(context).spot\u list\u title),centerTitle:true),
主体:容器(
子:列(
儿童:[
扩大(
子:堆栈(
儿童:[
StreamBuilder(
流:_mBlock.mSpotStream,
生成器:(上下文,快照){
返回刷新指示器(
onRefresh:(){
返回_mBlock.getSpots();
},
子项:ListView.builder(
itemCount:snapshot.data?长度为0,
itemBuilder:(上下文、位置){
返回SpotListItem(快照.数据[位置],(){
ScaffoldMessenger.of(context).showSnackBar(SnackBar(内容:Text(position.toString())));
});
},
),
);
},
),
StreamBuilder(
流:_mBlock.mErrorStream,
生成器:(上下文,快照){
if(snapshot.hasData){
SchedulerBinding.instance.addPostFrameCallback((){
显示对话框(
上下文:上下文,
禁止:错误,
建筑商:(){
返回脚手架(
正文:中(
孩子:升起按钮(
子项:文本('disclose'),
已按下:(){
Navigator.pop(上下文);
},
),
),
);
},
);
});
返回容器(
宽度:0.0,
高度:0.0,
);
}否则{
返回容器(
宽度:0.0,
高度:
class SpotListScreen extends StatelessWidget {
final SpotListBlock _mBlock = SpotListBlock();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(Strings.of(context).spot_list_title), centerTitle: true),
body: Container(
child: Column(
children: [
Expanded(
child: Stack(
children: [
StreamBuilder<List<SpotDto>>(
stream: _mBlock.mSpotStream,
builder: (context, snapshot) {
return RefreshIndicator(
onRefresh: () {
return _mBlock.getSpots();
},
child: ListView.builder(
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, position) {
return SpotListItem(snapshot.data[position], () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(position.toString())));
});
},
),
);
},
),
StreamBuilder<Error<String>>(
stream: _mBlock.mErrorStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
SchedulerBinding.instance.addPostFrameCallback((_) {
showDialog(
context: context,
barrierDismissible: false,
builder: (_) {
return Scaffold(
body: Center(
child: RaisedButton(
child: Text('dismiss'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
},
);
});
return Container(
width: 0.0,
height: 0.0,
);
} else {
return Container(
width: 0.0,
height: 0.0,
);
}
},
),
Column(
children: [
Expanded(
child: StreamBuilder<Progress<bool>>(
stream: _mBlock.mStateStream,
builder: (context, snapshot) {
return Visibility(
visible: snapshot.data?.mIsLoading ?? false,
child: SizedBox.expand(
child: Container(
color: Colors.blue.withOpacity(Dimens.overlayOpacity),
child: Center(
child: CircularProgressIndicator(),
),
),
),
);
},
),
)
],
)
],
))
],
)),
);
}
}
Future<List<SpotDto>> getSpots() {
var completer = new Completer<List<SpotDto>>();
_reportsRepositoryImpl.getSpots().single.then((spotList) {
addNewSpotsToList(spotList);
completer.complete(spotList);
}).catchError((Object obj) {
switch (obj.runtimeType) {
case DioError:
_mErrorSink.add(Error((obj as DioError).message));
completer.complete();
break;
default:
completer.complete();
}
_mSpotSink.add(_mSpotList);
});
return completer.future;
}