Firebase 颤振:来自firestore的延迟负载数据

Firebase 颤振:来自firestore的延迟负载数据,firebase,asynchronous,flutter,dart,google-cloud-firestore,Firebase,Asynchronous,Flutter,Dart,Google Cloud Firestore,注意:我已经看到了关于ListView延迟加载的答案,但这些是针对自定义API而不是firestore数据库的 我有一个图书摘要应用程序,该应用程序从我的Firebase/Firestore数据库中获取数据,然后使用ListView.builder显示它,它包装在StreamBuilder中 现在,我想延迟获取数据,我的意思是当用户滚动列表时,所需的数据会被加载,而不是一次加载数据然后延迟显示 //The Widget used to display data: Widget feed() {

注意:我已经看到了关于ListView延迟加载的答案,但这些是针对自定义API而不是firestore数据库的

我有一个图书摘要应用程序,该应用程序从我的
Firebase/Firestore
数据库中获取数据,然后使用
ListView.builder
显示它,它包装在
StreamBuilder

现在,我想延迟获取数据,我的意思是当用户滚动列表时,所需的数据会被加载,而不是一次加载数据然后延迟显示

//The Widget used to display data:

Widget feed() {
  return Container(
    width: deviceWidth,
    height: deviceHeight / 3,
    child: StreamBuilder(
        stream: Firestore.instance
            .collection('feedItem')
            .orderBy('feedId', descending: true)
            .snapshots(),

        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (snapshot.hasData) {
            int totalLength = snapshot.data.documents.length;
            return ListView.builder(
              scrollDirection: Axis.horizontal,
              itemCount: totalLength > 10 ? 10 : totalLength,
              itemBuilder: (BuildContext context, int index) {
                return Container(
                  width: deviceWidth / 2.5,
                  child: GestureDetector(
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (BuildContext context) => FeedIntro(
                                  snapshot.data.documents[
                                      ((totalLength - 1) - index)]['feedId'])));
                    },
                    child: Card(
                        child: Column(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: <Widget>[
                        Container(
                          // width: 150,
                          height: 150,
                          foregroundDecoration: BoxDecoration(
                              image: DecorationImage(
                                  image: NetworkImage(
                                    snapshot.data.documents[index]['feedImage'],
                                  ),
                                  fit: BoxFit.fill)),
                        ),
                        Center(
                            child: Padding(
                          padding: const EdgeInsets.all(8.0),
                          child: Text(snapshot.data.documents[index]['title']),
                        )),
                      ],
                    )),
                  ),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Center(child: Text('Sorry Something went wrong!'));
          } else {
            return Center(
              child: SizedBox(
                child: CircularProgressIndicator(),
                width: 50,
                height: 50,
              ),
            );
          }
        }),
  );
}
//用于显示数据的小部件:
小部件提要(){
返回容器(
宽度:设备宽度,
高度:设备高度/3,
孩子:StreamBuilder(
流:Firestore.instance
.collection('feedItem')
.orderBy('feedId',降序:true)
.snapshots(),
生成器:(BuildContext上下文,异步快照){
if(snapshot.hasData){
int totalLength=snapshot.data.documents.length;
返回ListView.builder(
滚动方向:轴水平,
项目计数:总长度>10?10:总长度,
itemBuilder:(构建上下文,int索引){
返回容器(
宽度:设备宽度/2.5,
儿童:手势检测器(
onTap:(){
导航器。推(
上下文
材料路线(
生成器:(BuildContext上下文)=>FeedIntro(
快照.数据.文档[
((总长度-1-指数)][feedId]);;
},
孩子:卡片(
子:列(
mainAxisAlignment:mainAxisAlignment.start,
儿童:[
容器(
//宽度:150,
身高:150,
前场装饰:盒子装饰(
图像:装饰图像(
图片:NetworkImage(
snapshot.data.documents[索引]['feedImage'],
),
适合:BoxFit.fill),
),
居中(
孩子:填充(
填充:常数边集全部(8.0),
子项:文本(快照.数据.文档[索引]['title']),
)),
],
)),
),
);
},
);
}else if(snapshot.hasrerror){
返回中心(child:Text('Sorry Something should!'));
}否则{
返回中心(
孩子:大小盒子(
子对象:CircularProgressIndicator(),
宽度:50,
身高:50,
),
);
}
}),
);
}

对延迟加载的描述似乎与分页匹配。下面是一个在
ListView.builder中使用带分页的Firestore的简单演示

此示例实现了Firebase官方文档中的代码段

在本演示中,有两种方法可以在视图上加载数据

  • 使用刷新整个
    列表视图
  • 向下滚动以点击列表底部,加载
    列表视图中的下一个文档。
    用于确定用户是否已点击列表的底部
import'包:cloud_firestore/cloud_firestore.dart';
导入“包:firebase_core/firebase_core.dart”;
进口“包装:颤振/材料.省道”;
输入'DocObj.dart';
Future main()异步{
WidgetsFlutterBinding.ensureInitialized();
//初始化Firebase
等待Firebase.initializeApp();
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
//此小部件是应用程序的根。
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振演示”,
主题:主题数据(
主样本:颜色。蓝色,
视觉密度:视觉密度。自适应平台密度,
),
主页:MyHomePage(标题:“颤振演示主页”),
);
}
}
类MyHomePage扩展StatefulWidget{
MyHomePage({Key,this.title}):超级(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>\u MyHomePageState();
}
类_MyHomePageState扩展状态{
var scrollController=scrollController();
@凌驾
void initState(){
super.initState();
getDocuments();
scrollController.addListener((){
if(scrollController.position.atEdge){
如果(scrollController.position.pixels==0)
打印(“顶部的列表视图滚动”);
否则{
打印(“底部的列表视图滚动”);
getDocumentsNext();//加载下一个文档
}
}
});
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子项:listDocument.length!=0
?刷新指示器(
子项:ListView.builder(
物理:AlwaysScrollableScrollPhysics(),
控制器:滚动控制器,
itemCount:listDocument.length,
itemBuilder:(上下文,索引){
返回列表块(
标题:文本(“${listDocument[index].documentName}”),
);
},
),
onRefresh:getDocuments,//刷新整个列表
)
:CircularProgressIndicator(),
),
);
}
清单文件;
QuerySnapshot采集状态;
//获取前15个文档
Future getDocuments()异步{
列表文档=
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';

class Sample extends StatefulWidget {
  @override
  _SampleState createState() => _SampleState();
}

class _SampleState extends State<Sample> {
  ScrollController _chatScrollController;
  int loadMoreMsgs = 25; // at first it will load only 25
  int a = 50; // 'loadMoreMsgs' will added by 'a' if we load more msgs in listview.
  
  @override
  void initState() {
    _chatScrollController = ScrollController()
      ..addListener(() {
        if (_chatScrollController.position.atEdge) {
          if (_chatScrollController.position.pixels == 0)
            print('ListView scrolled to top');
          else {
            setState(() {
              loadMoreMsgs =  loadMoreMsgs + a;
            });
            print('ListView scrolled to bottom');
          }
        }
      });
    super.initState();
  }
  
  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: FirebaseFirestore.instance.collection('CollectionName').limit(loadMoreMsgs).snapshots(),
      builder: (context, snapshot) {
        return ListView.builder(
          controller: _chatScrollController,
          itemBuilder: (context, index) {
            return Text('This is a sample');
          },
        );
      },
    );
  }
}