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;
  }