如何在Flutter中使用StreamBuilder将连接建立为等待状态

时间:2019-09-12 14:19:22

标签: flutter

我的要求是使StreamBuilder连接状态为等待状态。

我正在使用发布主题,每当我想在流生成器中加载数据时,我只是通过调用 postStudentsToAssign()方法将数据添加到接收器中,在此此方法进行API调用,需要一些时间,在那段时间内,我想让streamBuilder连接状态变为等待状态

流生成器:

StreamBuilder(
            stream: studentsBloc.studentsToAssign,
            // initialData: [],
            builder: (context, snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.waiting:
                  // While waiting for the data to load, show a loading spinner.
                  return getLoader();
                default:
                  if (snapshot.hasError)
                    return  Center(child: Text('Error: ${snapshot.error}'));
                  else
                    return  _getDrawer(snapshot.data);
              }
            }),

初始化可观察对象:

 final _assignStudentSetter = PublishSubject<dynamic>();

 Observable<List<AssignMilestoneModel>> get studentsToAssign =>
      _studentsToAssignFetcher.stream;

将数据添加到流的方法:

 postStudentsToAssign(int studyingClass, String milestoneId, String subject,
      List studentList) async {
    var response = await provider.postAssignedStudents(
        studyingClass, milestoneId, subject, studentList);
    _assignStudentSetter.sink.add(response);
  }

1 个答案:

答案 0 :(得分:1)

您可以将null发送到流,因此snapshot.connectionState变为active。我不知道为什么以及它是否是官方解决方案,但它有效(至少现在)。我偶然发现了这个。 我希望Flutter团队解释如何设置快照的connectionState。 StreamBuilder文档尚不清楚。看来您应该用新的流替换流,以使snapshot处于waiting状态。但这又是您要实现的逻辑。

我在接收到StreamBuilder的数据更改之后,检查了AsyncSnapshot.connectionState的源以发现waitingactive开头(在连接流之后)。如果snapshot.hasData,则snapshot.data != null返回true。这就是以下代码的工作方式。

class SearchScreen extends StatelessWidget {

  final StreamController<SearchResult> _searchStreamController = StreamController<SearchResult>();
  final SearchService _service = SearchService();

  void _doSearch(String text) async {
    if (text?.isNotEmpty ?? false) {
      _searchStreamController.add(null);
      _searchService.search(text)
          .then((SearchResult result) => _searchStreamController.add(result))
          .catchError((e) => _searchStreamController.addError(e));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(children: <Widget>[
        SearchBar(
          onChanged: (text) => _doSearch(text),
        ),
        StreamBuilder<SearchResult>(
          stream: _searchStreamController.stream,
          builder: (BuildContext context, AsyncSnapshot<SearchResult> snapshot) {
            Widget widget;
            if (snapshot.hasData) {
              widget = Expanded(
                // show search result
              );
            }
            else if (snapshot.hasError) {
              widget = Expanded(
                 // show error
              );
            }
            else if(snapshot.connectionState == ConnectionState.active){
              widget = Expanded(
                // show loading
              );
            }
            else {
              // empty
              widget = Container();
            }
            return widget;
          },
        ),
      ]),
    );
  }
}