首页 > 解决方案 > 如何将 Futurebuilder 更改为 Streambuilder?

问题描述

我在一种方法中使用了一个未来的构建器,并试图切换到一个 Streambuilder,但是我的代码可能是任何人都可以提供帮助的

class _MeineFreundeState extends State<MeineFreunde> {
  Icon custIcon = Icon(Icons.search);
  Widget cusSearchBar = Text("Meine Freunde");
  Stream myVideos;
  int likes = 0;
  int videos = 0;
  int followers;
  int following;
  bool dataisthere = false;
  @override
  void initState() {
    super.initState();
    getalldata();
  }

  getalldata() async {
    var listOfIds = [];
    String myID = FirebaseAuth.instance.currentUser.uid;
    var idofotheruser = await FirebaseFirestore.instance
        .collection('meinprofilsettings')
        .doc(myID)
        .collection('following')
        .get();
    following = idofotheruser.docs.length;
    idofotheruser.docs.forEach((element) {
      listOfIds.add(element.id);
    });
    print(listOfIds);

    myVideos = FirebaseFirestore.instance
        .collection('videos')
        .where('uid', isEqualTo: 'Fp3unLwcl2SGVh4MbUPiRVAylYV2')
        .snapshots();
    var documents = await FirebaseFirestore.instance
        .collection('videos')
        .where('uid', isEqualTo: 'Fp3unLwcl2SGVh4MbUPiRVAylYV2')
        .get();

    if (!mounted) return;
    setState(() {
      videos = documents.docs.length;
    });
    for (var item in documents.docs) {
      likes = item.data()['likes'].length + likes;
    }
    var followersdocuments = await FirebaseFirestore.instance
        .collection("meinprofilsettings")
        .doc(myID)
        .collection('followers')
        .get();
    var followingdocuments = await FirebaseFirestore.instance
        .collection("meinprofilsettings")
        .doc(myID)
        .collection('following')
        .get();
    followers = followersdocuments.docs.length;
    following = followingdocuments.docs.length;

    setState(() {
      dataisthere = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    return getBody(context);
  }

  Widget getBody(BuildContext context) {
    return dataisthere == false
        ? Scaffold(body: Center(child: CircularProgressIndicator()))
        : Stack(children: <Widget>[
            Scaffold(
              appBar: AppBar(
                actions: [
                  IconButton(
                    icon: Icon(Icons.search),
                    onPressed: () {
                      Navigator.of(context)
                          .pushNamed(Searchuserinmeinebeitraege.route);
                    },
                  ),
                ],
                backgroundColor: Colors.transparent,
                elevation: 0.0,
              ),
              body: RefreshIndicator(
                onRefresh: _handleRefresh,
                color: Colors.black,
                strokeWidth: 4,
                child: ListView(
                  children: [
                    Column(children: <Widget>[
                      SizedBox(
                        height: 5,
                      ),
                      StreamBuilder(
                          stream: myVideos,
                          builder: (context, snapshot) {
                            if (snapshot.connectionState ==
                                ConnectionState.waiting) {
                              return Center(child: CircularProgressIndicator());
                            }

                            if (videos > 0) {
                              return StaggeredGridView.countBuilder(
                                scrollDirection: Axis.vertical,
                                shrinkWrap: true,
                                physics: ScrollPhysics(),
                                crossAxisCount: 3,
                                itemCount: snapshot.data.docs.length,
                                itemBuilder: (context, index) {
                                  DocumentSnapshot video =
                                      snapshot.data.docs[index];
                                  return InkWell(
                                    onTap: () {
                                      NavigationService.instance
                                          .navigateToRoute(MaterialPageRoute(
                                              builder: (context) {
                                        return VideoPage(
                                          video.data()['videourl'],
                                          video.data()['uid'],
                                          video.id,
                                        );
                                      }));
                                    },
                                    child: Card(
                                      elevation: 0.0,
                                      child: ClipRRect(
                                        borderRadius: BorderRadius.circular(25),
                                        clipBehavior:
                                            Clip.antiAliasWithSaveLayer,
                                        child: Image.network(
                                          video.data()['previewimage'],
                                          fit: BoxFit.cover,
                                        ),
                                      ),

                                      //imageData: searchImages[index],
                                    ),
                                  );
                                },
                                staggeredTileBuilder: (index) =>
                                    StaggeredTile.count(
                                        (index % 7 == 0) ? 2 : 1,
                                        (index % 7 == 0) ? 2 : 1),
                                mainAxisSpacing: 8.0,
                                crossAxisSpacing: 4.0,
                              );
                            } else {
                              return Center(
                                child: Padding(
                                  padding:
                                      const EdgeInsets.fromLTRB(0, 100, 0, 0),
                                  child: Container(
                                    child: Text(
                                      "No Videos Yet",
                                      style: TextStyle(
                                          fontSize: 18, color: Colors.black),
                                    ),
                                  ),
                                ),
                              );
                            }
                          }),
                    ]),
                  ],
                ),
              ),
            ),
          ]);
  }

  Future _handleRefresh() async {
    await Future.delayed(new Duration(seconds: 2));
    setState(() {
      getalldata();
    });
    return null;
  }
}

我是颤振的初学者,我知道我可以将 FuturBuilder 更改为 Streambuilder,然后将来进行流式传输,但是我如何获取数据有什么不同我的意思是像这条线

 video.data()['videourl'],

它是否相等或有什么区别,以及如何在 getalldata 方法中更改它。如果您需要更多信息,请发表评论。

标签: firebaseflutterstreamflutter-futurebuilder

解决方案


StreamBuilder在很多方面与FutureBuilder不同,其中一个主要区别是

FutureBuilder 的主要工作是完成未来并在返回结果后返回结果,除非其父级重建,否则无法从未来获取最新的快照。一旦附加的未来返回结果,构建器方法就会被执行以刷新 Ui。

在使用 StreamBuilder 时,它会持续监听您指定的集合并实时获取最新的快照。这意味着您的 firestore 集合中的任何文档都会更改,您将获得最新更新的集合,并且构建器方法会重建以刷新 UI。

您可以像这样使用 StreamBuilder 从您的 firestore 集合中获取数据

 String myID = FirebaseAuth.instance.currentUser.uid;
   final  queryVideos = await FirebaseFirestore.instance
         .collection('videos')
        .where('uid', arrayContains: listOfIds)

StreamBuilder<DocumentSnapshot>(
        stream: queryVideos.snapshots(),
        builder:
            (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.data == null) {
             return Center(child: CircularProgressIndicator()); /// show a loader
        } else if (snapshot.data.docs.isEmpty) {
            return const SizedBox.shrink(); // show an empty widget no docs
       } else
           return StaggeredGridView.countBuilder(
                   scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                     physics: ScrollPhysics(),
                     crossAxisCount: 3,
                     itemCount: snapshot.data.docs.length,
                     itemBuilder: (context, index) {
                     /// fetch a doc by Index
                     final doc = snapshot.data.docs[index];
                     return InkWell(
                              onTap: () {
                                NavigationService.instance
                                .navigateToRoute(MaterialPageRoute(
                                   builder: (context)=>VideoPage(
                                          doc['videourl'], // this is how you access each property in a document
                                          doc['uid'],
                                          doc['id']
                                         ));
                                },
                     child: YourWidget());
                   }));

    });


推荐阅读