我用Flutter Firebase做了一个社交媒体应用,和所有社交媒体应用一样,我在主屏幕上有用户分享的帖子流,一开始我没有遇到任何问题,但是随着数据量的增加,我开始遇到问题,尤其是获取照片。后来我发现这是因为我正在一次获取所有的数据,并决定使用分页。我已经成功地使用了分页,我也开始使用缓存的网络图像来更快地加载我的照片。但是我在流程上还是有这样一个问题,当我把屏幕滚动到底部的时候,数据是在我设置的限制下加载的,在这个例子中我的限制是12,所以我在向下滚动屏幕的时候没有问题,但当我想快速向上滚动屏幕时,它尝试再次加载所有数据,系统遇到太多困难,我无法在最后加载它,应用程序发出连接丢失错误并自行关闭。
在我看来,当我们向上滑动屏幕时,同样的事情应该会发生,就像向下滑动屏幕时,数据会按照我们设置的限制数量一点一点地加载。
否则,我遇到的这个问题就会发生。
你知道解决这个问题的办法吗?
这是我的分页代码;
getData() async {
var Ref1 = (widget.post != null)
? _firestore
.collection("users")
.doc(widget.post["profileID"])
.collection("Datas")
.orderBy("uploadTime", descending: true)
.limit(perpage)
: null;
setState(() {
loadingProducts = true;
});
var reponse = await Ref1.get();
listt = reponse.docs;
lastDocument = reponse.docs[reponse.docs.length - 1];
setState(() {
loadingProducts = false;
});
}
getmoreData() async {
if (moreDataAvailable == false) {
return;
}
if (gettingmoreData == true) {
return;
}
setState(() {
gettingmoreData = true;
});
var Ref1 = (widget.post != null)
? _firestore
.collection("users")
.doc(widget.post["profileID"])
.collection("Datas")
.orderBy("uploadTime", descending: true)
.startAfterDocument(lastDocument)
.limit(perpage)
: null;
var reponse = await Ref1.get();
if (reponse.docs.length < perpage) {
moreDataAvailable = false;
}
lastDocument = reponse.docs[reponse.docs.length - 1];
listt.addAll(reponse.docs);
setState(() {});
setState(() {
gettingmoreData = false;
});
}
这是我的建造者
GridView.builder(
controller: scrollController,
physics: ScrollPhysics(),
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
itemCount: listt.length,
itemBuilder: (context, index) {
return GestureDetector(
onTap: () =>
navigateToDetail(listt[index]),
child: Hero(
tag: (listt[index]["foto"] != null)
? NetworkImage(
listt[index]["foto"])
: AssetImage(
"assets/images/n_image.jpg"),
child: Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Container(
height: size.height * 0.078,
width: double.infinity,
decoration: BoxDecoration(
borderRadius:
BorderRadius.only(
bottomRight:
Radius.circular(
10.0),
bottomLeft:
Radius.circular(
10.0),
),
color: Colors.grey[600]
.withOpacity(0.5)),
child: Center(
child: AutoSizeText(
"${listt[index]["name"]}",
textAlign:
TextAlign.center,
style: GoogleFonts.lora(
textStyle: TextStyle(
color: Colors.white,
fontSize: 15,
),
),
maxLines: 2,
),
),
),
],
),
margin: EdgeInsets.all(5.0),
decoration: BoxDecoration(
image: DecorationImage(
image: (listt[index]
["foto"] !=
null)
? OptimizedCacheImageProvider(
listt[index]["foto"])
: AssetImage(
"assets/images/n_image.jpg"),
fit: BoxFit.cover,
),
color: Colors.white,
borderRadius:
BorderRadius.circular(10.0),
),
),
),
);
},
),
和IM监听控制器在initstate与此;
scrollController.addListener(() {
double maxScroll = scrollController.position.maxScrollExtent;
double currentScroll = scrollController.position.pixels;
double delta = MediaQuery.of(context).size.height * 0.25;
if (maxScroll - currentScroll <= delta) {
getmoreTarif();
}
});
1条答案
按热度按时间y1aodyip1#
当前代码跟踪当前结果的最后一个文档,然后用该文档调用
startAfterDocument
以获取下一组结果。这适用于向前滚动,但不适用于向后滚动。要向后分页,还需要跟踪当前结果的first文档,然后用该文档调用endBeforeDocument
。