首页 > 解决方案 > 如果网络请求失败,如何在流的基础上显示警报对话框

问题描述

这是我到目前为止的代码。 _mBlock.mSpotStream是网络请求。我很感兴趣如何在_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();
      }
    },
  );
}

标签: flutterflutter-layoutbloc

解决方案


最后,我已经像这样修复了它,这是我能够修复它的唯一方法,任何评论都值得赞赏:我的修复基于这个要点https://gist.github.com/felangel/75f1ca6fc954f3672daf7962577d56f5

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

推荐阅读