Firebase 在TabBarView中加载firestore数据

Firebase 在TabBarView中加载firestore数据,firebase,flutter,google-cloud-firestore,flutter-layout,Firebase,Flutter,Google Cloud Firestore,Flutter Layout,我试图创建一个用户界面,在主页中,用户有3个选项卡:组、事件、朋友。 我已经为每个选项卡构建了一个StreamBuilder,但是当我在选项卡之间切换时,它会抛出一个错误,表示流已经被监听 我需要一种方法来“重置”流,这样当我切换回选项卡时,它可以再次加载,即使我已经听了那个流 这是拖缆的代码-我目前只尝试访问事件数据,稍后每个选项卡将有不同的流 Stream<List<DocumentSnapshot>> _streamer() async* { //this is c

我试图创建一个用户界面,在主页中,用户有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;
}
Stream\u streamer()async*{//这是当前唯一的拖缆-它只加载事件。
var userEventsDocument=await Firestore.instance
.collection('userEvents')
.document(widget.uid)
.get();
var userEvents=List.from(userEventsDocument[“eventlist]”);
List events snapshot=List();
对于(var i=0;i
以下是im在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,
                ),
              ),
            )
          ],
        )
      );
    },
  ),
]),
TabBarView(控制器:\ tabController,子级:[
StreamBuilder(
流:_拖缆(),
//Firestore.instance.collection(“事件”).snapshots(),
生成器:(BuildContext上下文,异步快照){
如果(!snapshot.hasData)返回常量文本(“加载…”);
返回大小框(
高度:MediaQuery.of(上下文).size.height-
42 -
MediaQuery.of(context.padding.bottom)-
AppBar().preferredSize.height-
kToolbarHeight,
子:列(
儿童:[
扩大(
子:容器(
子项:ListView.separated(
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引)=>
_buildListItem(上下文、快照.数据[索引]),
separatorBuilder:(上下文,索引){
返回分隔符();
},
收缩膜:对,
),
),
)
],
)
);
},
),
StreamBuilder(
流:_拖缆(),
//Firestore.instance.collection(“事件”).snapshots(),
生成器:(BuildContext上下文,
异步快照(快照){
如果(!snapshot.hasData)返回常量文本(“加载…”);
返回大小框(
高度:MediaQuery.of(上下文).size.height-
42 -
MediaQuery.of(context.padding.bottom)-
AppBar().preferredSize.height-
kToolbarHeight,
子:列(
儿童:[
扩大(
子:容器(
子项:ListView.separated(
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引)=>
_buildListItem(上下文、快照.数据[索引]),
separatorBuilder:(上下文,索引){
返回分隔符();
},
收缩膜:对,
),
),
)
],
)
);
},
),
StreamBuilder(
流:_拖缆(),
//Firestore.instance.collection(“事件”).snapshots(),
生成器:(BuildContext上下文,
异步快照(快照){
如果(!snapshot.hasData)返回常量文本(“加载…”);
返回大小框(
高度:MediaQuery.of(上下文).size.height-
42 -
MediaQuery.of(context.padding.bottom)-
AppBar().preferredSize.height-
kToolbarHeight,
子:列(
儿童:[
扩大(
子:容器(
子项:ListView.separated(
itemCount:snapshot.data.length,
itemBuilder:(上下文,索引)=>
_buildListItem(上下文、快照.数据[索引]),
separatorBuilder:(上下文,索引){
返回分隔符();
},
收缩膜:对,
),
),
)
],
)
);
},
),
]),

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

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

每个测试屏幕都有一个生成器,它使用自己的streambuilder返回listview。

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

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

每个测试屏幕都有一个生成器,它使用自己的streambuilder返回listview。

您是否尝试过使用状态管理解决方案在中心位置监听流,然后直接读取这些流的输出?您能再解释一下吗?我对你提到的内容不太熟悉你是否在你的应用程序上使用了任何类型的状态管理解决方案,比如Redux、BLoC、ScopedModel、Provider或其他什么?我没有,我读过BLoC的相关文章,但我没有真正弄明白如何在我的设计中实现它来避免尝试重新收听已收听的流的问题,您必须将这些流放在应用程序的中心位置,然后将其传递到选项卡。而不是每次加载选项卡时都听流。您是否尝试过使用状态管理解决方案在中心位置听流,然后只喝这些流的输出?您能再解释一下吗?我对你提到的内容不太熟悉你是否在你的应用程序上使用了任何类型的状态管理解决方案,比如Redux、BLoC、ScopedModel、Provider或其他什么?我没有,我读过BLoC的相关文章,但我没有真正弄明白如何在我的设计中实现它来避免尝试重新收听已收听的流的问题,您必须将这些流放在应用程序的中心位置,然后将其传递到选项卡。而不是每次加载选项卡时都侦听流。