在TabBarView中加载Firestore数据

时间:2020-07-16 10:08:30

标签: firebase flutter google-cloud-firestore flutter-layout

我正在尝试创建一个UI,该用户在主页中具有3个选项卡:组,事件,朋友。 我为每个选项卡构建了一个StreamBuilder,但是当我在各个选项卡之间切换时,它会引发错误,表示流已经被监听。

我需要一种“重置”流的方法,因此即使我已经收听了该流,它也可以在我切换回标签时再次加载。

这是流媒体的代码-我目前仅尝试访问事件数据,稍后每个选项卡会有不同的流。

Stream<List<DocumentSnapshot>> _streamer() async* { //this is currently the only streamer - it only loads events.   
  var userEventsDocument = await Firestore.instance
      .collection('userEvents')
      .document(widget.uid)
      .get();

  var userEvents = List.from(userEventsDocument["eventlist"]);
  List<DocumentSnapshot> eventsSnapshot = List();

  for (var i = 0; i < userEvents.length; i++) {
    eventsSnapshot.add(await userEvents[i].get());
  }

  yield eventsSnapshot;
}

这是在TabBarView中使用流光的方式:

TabBarView(controller: _tabController, children: [
  StreamBuilder(
    stream: _streamer(),
    //Firestore.instance.collection("Events").snapshots(),
    builder: (BuildContext context, AsyncSnapshot<List<dynamic>> snapshot) {
      if (!snapshot.hasData) return const Text("Loading...");
      return SizedBox(
        height: MediaQuery.of(context).size.height -
          42 -
          MediaQuery.of(context).padding.bottom -
          AppBar().preferredSize.height -
          kToolbarHeight,
        child: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                child: ListView.separated(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) =>
                      _buildListItem(context, snapshot.data[index]),
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                  shrinkWrap: true,
                ),
              ),
            )
          ],
        )
      );
    },
  ),
  StreamBuilder(
    stream: _streamer(),
    //Firestore.instance.collection("Events").snapshots(),
    builder: (BuildContext context,
        AsyncSnapshot<List<dynamic>> snapshot) {
      if (!snapshot.hasData) return const Text("Loading...");
      return SizedBox(
        height: MediaQuery.of(context).size.height -
            42 -
            MediaQuery.of(context).padding.bottom -
            AppBar().preferredSize.height -
            kToolbarHeight,
        child: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                child: ListView.separated(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) =>
                      _buildListItem(context, snapshot.data[index]),
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                  shrinkWrap: true,
                ),
              ),
            )
          ],
        )
      );
    },
  ),
  StreamBuilder(
    stream: _streamer(),
    //Firestore.instance.collection("Events").snapshots(),
    builder: (BuildContext context,
        AsyncSnapshot<List<dynamic>> snapshot) {
      if (!snapshot.hasData) return const Text("Loading...");
      return SizedBox(
        height: MediaQuery.of(context).size.height -
            42 -
            MediaQuery.of(context).padding.bottom -
            AppBar().preferredSize.height -
            kToolbarHeight,
        child: Column(
          children: <Widget>[
            Expanded(
              child: Container(
                child: ListView.separated(
                  itemCount: snapshot.data.length,
                  itemBuilder: (context, index) =>
                      _buildListItem(context, snapshot.data[index]),
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                  shrinkWrap: true,
                ),
              ),
            )
          ],
        )
      );
    },
  ),
]),

1 个答案:

答案 0 :(得分:0)

我通过将小部件传递到TabBarview来做到这一点:

body: TabBarView(controller: _tabController, children:
              [TestScreen1(), TestScreen2(), TestScreen3()],
),

每个TestScreens都有一个生成器,该生成器使用其自己的streambuilder返回一个列表视图。