Firebase 如何在listview中添加更多滚动项目?
此代码当前加载存储在Firestore集合中的所有啤酒。。我怎样才能在开始时只加载10杯啤酒,然后在用户向下滚动并到达10杯啤酒列表的末尾时加载。在最后一杯啤酒之后,应该再加载10杯。并且应该根据时间戳对啤酒进行排序Firebase 如何在listview中添加更多滚动项目?,firebase,flutter,google-cloud-firestore,flutter-layout,Firebase,Flutter,Google Cloud Firestore,Flutter Layout,此代码当前加载存储在Firestore集合中的所有啤酒。。我怎样才能在开始时只加载10杯啤酒,然后在用户向下滚动并到达10杯啤酒列表的末尾时加载。在最后一杯啤酒之后,应该再加载10杯。并且应该根据时间戳对啤酒进行排序 class BrewList extends StatefulWidget { @override _BrewListState createState() => _BrewListState(); } class _BrewListState extends St
class BrewList extends StatefulWidget {
@override
_BrewListState createState() => _BrewListState();
}
class _BrewListState extends State<BrewList> {
List<Brew> brews = [];
ScrollController _controller = ScrollController();
@override
void initState() {
_startFirst();
super.initState();
_controller.addListener(_scrollListener);
}
_scrollListener() {
setState(() {
if (_controller.position.atEdge) {
if (_controller.position.pixels == 0) {
} else {
}
}
});
}
_startFirst() async {
brews = await DatabaseService().brews ?? [];
setState(() {
brews = brews;
});
}
@override
Widget build(BuildContext context) {
Future<void> _refreshBrews() async {
List<Brew> tempList = await DatabaseService().brews;
setState(() {
brews = tempList;
});
print(brews);
}
return RefreshIndicator(
onRefresh: _refreshBrews,
child: ListView.builder(
controller: _controller,
itemCount: brews.length,
itemBuilder: (context, index) {
return BrewTile(brew: brews[index]);
},
),
);
}
}
Future<List<Brew>> get brewss async {
QuerySnapshot snapshot = await brewsCollection
.orderBy('timestamp', descending: true)
.limit(2)
.getDocuments();
return _postListFromSnapshot(snapshot);
}
类BrewList扩展StatefulWidget{
@凌驾
_BrewListState createState()=>\u BrewListState();
}
类_BrewListState扩展了状态{
列表酿造=[];
ScrollController_controller=ScrollController();
@凌驾
void initState(){
_startFirst();
super.initState();
_controller.addListener(_scrollListener);
}
_scrollListener(){
设置状态(){
if(_controller.position.atEdge){
如果(_controller.position.pixels==0){
}否则{
}
}
});
}
_startFirst()异步{
brews=等待DatabaseService().brews???[];
设置状态(){
酿造=酿造;
});
}
@凌驾
小部件构建(构建上下文){
Future\u refreshBrews()异步{
List templast=wait DatabaseService().brews;
设置状态(){
酿造=圣堂武士;
});
印刷品(酿造);
}
返回刷新指示器(
onRefresh:_refreshBrews,
子项:ListView.builder(
控制器:_控制器,
itemCount:brews.length,
itemBuilder:(上下文,索引){
返回BrewTile(brew:brews[index]);
},
),
);
}
}
未来获取BREWS异步{
QuerySnapshot snapshot=wait brewsCollection
.orderBy('timestamp',降序:true)
.限额(2)
.getDocuments();
返回_postlistfromsapshot(快照);
}
您可以使用滚动控制器和侦听器来确定用户是否已滚动到屏幕底部。如果有,则从数据库服务加载接下来的10项
这看起来像下面这样
ScrollController _controller = ScrollController();
@override
void initState() {
super.initState();
// add listener
_controller.addListener(_scrollListener);
}
_scrollListener() {
setState(() {
if (_controller.position.atEdge) {
if (_controller.position.pixels == 0)
{
// user is at top of the list
}
else
{
// user is at the bottom of the list.
// load next 10 items and add them to the list of items in the list.
}
}
});
}
不确定以下内容是否有用,但以下是我在颤振应用程序中所做的。请特别注意底部的_onScroll函数
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import '../../blocs/feed_bloc/feed_events.dart';
import '../../blocs/feed_bloc/bloc.dart';
import '../../blocs/feed_bloc/feed_state.dart';
import './post.dart';
import '../loader.dart';
class Feed extends StatefulWidget {
Feed({ Key key }): super(key: key);
@override
_FeedState createState() => _FeedState();
}
class _FeedState extends State<Feed> {
final _scrollController = ScrollController();
final _scrollThreshold = 300.0;
FeedBloc _feedBloc;
_FeedState();
@override
void initState() {
super.initState();
_scrollController.addListener(_onScroll);
_feedBloc = BlocProvider.of<FeedBloc>(context);
}
@override
Widget build(BuildContext context) {
return BlocBuilder<FeedBloc, FeedState>(
builder: (context, state) {
if (state is FeedUninitialized) {
_feedBloc.add(Init());
return Loader();
}
if (state is FeedLoading) {
return Loader();
}
if (state is FeedLoaded) {
return new RefreshIndicator(
child: ListView(
controller: _scrollController,
// Important: Remove any padding from the ListView.
padding: EdgeInsets.zero,
children: state.posts.map((post) {
return Post(
postModel: state.postMap[post]
);
}).toList(),
),
onRefresh: () {
_feedBloc.add(Refresh());
return new Future.delayed(new Duration(seconds: 1));
},
);
}
return Center(
child: SizedBox(
height: 33,
child: Text(
'Sorry, there was a problem loading the feed.',
style: TextStyle( color: Colors.white)
),
),
);
}
);
}
int lastScroll = 0;
void _onScroll() {
if (new DateTime.now().millisecondsSinceEpoch - lastScroll > 1000) {
lastScroll = new DateTime.now().millisecondsSinceEpoch;
final maxScroll = _scrollController.position.maxScrollExtent;
final currentScroll = _scrollController.position.pixels;
if (maxScroll - currentScroll <= _scrollThreshold) {
_feedBloc.add(Fetch());
}
}
}
}
导入“包装:颤振/材料.省道”;
进口“包装:颤振团/颤振团.飞镖”;
导入“../../blocs/feed_bloc/feed_events.dart”;
导入“../blocs/feedu bloc/bloc.dart”;
导入“../../blocs/feed_bloc/feed_state.dart”;
导入“/post.dart”;
导入“../loader.dart”;
类提要扩展了StatefulWidget{
Feed({Key}):super(Key:Key);
@凌驾
_FeedState createState();
}
类_FeedState扩展状态{
final _scrollController=scrollController();
最终阈值=300.0;
feedblocu FeedBloc;
_FeedState();
@凌驾
void initState(){
super.initState();
_scrollController.addListener(_onScroll);
_feedBloc=BlocProvider.of(上下文);
}
@凌驾
小部件构建(构建上下文){
返回BlocBuilder(
生成器:(上下文、状态){
如果(状态为FeedUninitialized){
_add(Init());
返回加载器();
}
如果(状态为FeedLoading){
返回加载器();
}
如果(状态为FeedLoaded){
返回新的刷新指示器(
子:ListView(
控制器:\ u滚动控制器,
//重要提示:从ListView中删除任何填充。
填充:EdgeInsets.zero,
子项:state.posts.map((post){
回程站(
postModel:state.postMap[post]
);
}).toList(),
),
onRefresh:(){
_添加(刷新());
返回新的未来。延迟(新的持续时间(秒:1));
},
);
}
返回中心(
孩子:大小盒子(
身高:33,
子:文本(
“抱歉,加载提要时出现问题。”,
样式:TextStyle(颜色:Colors.white)
),
),
);
}
);
}
int lastcoll=0;
void _onScroll(){
if(new DateTime.now().millissecondssinceepoch-lastcoll>1000){
lastScroll=new DateTime.now().millissecondssinceepoch;
final maxScroll=\u scrollController.position.maxScrollExtent;
最终currentScroll=\u scrollController.position.pixels;
如果(maxScroll-currentScroll)首先你只想获取10个项目?可能是20个。但是我想在scroll上加载更多项目。非常感谢。但是你可以简化一下吗。我只是一个初学者,这看起来有点复杂。@pskinkyu有一个完整的工作小部件,只需使用它将来获取brews async{QuerySnapshot snapshot=wait brewsCollection.orderBy('timestamp',降序:true).getDocuments();返回_brewlistfromsapshot(snapshot);}这就是我获取当前列表的方式..我添加了scrollController..您是否可以向我展示我需要在此处添加的功能?您是指如何一次从firestore获取10个项目?最初使用上述代码..它加载列表中的所有啤酒..但我最初只想加载10个啤酒,然后在用户到达lis末尾时加载最初加载了10杯啤酒中的一杯..我想再加载10杯,以此类推..这与您如何使用某种查询对存储在firestore中的数据进行分页有关。我发现您之前已经询问过这一问题,并得到了合理的答案。基本上,您需要能够编写查询,以获得10块的文档。如果您有在文档上创建一个自动递增的整数属性,您可以通过该属性进行排序,然后最初选择该属性在0和11之间的位置。然后在第二个查询中,在10和21之间进行排序。这并没有回答我的问题,但感谢您所做的努力。我正在尝试找出如何排序从()开始的下一组数据最初加载到屏幕上的最后一组数据。@alex我明白了。我编辑了我的答案以包含c
Future<Map<String, dynamic>> getPosts({PostModel parent, PostModel lastPost}) async {
// First, we create the initial query.
// We pass in the parent key if there is one.
Query query = Firestore.instance
.collection('posts');
if (parent != null) {
query = query.where('parentId', isEqualTo: parent.key);
} else {
query = query.where('parentId', isNull: true);
}
query = query.orderBy('timestamp', descending: true);
// If we want to start at a certain doc (user is scrolling throught he feed)
// then we specify to start after a certain doc
if (lastPost != null) {
query = query.startAfterDocument(lastPost.rawDoc);
}
// Execute the query
final results = await query
.limit(18)
.getDocuments();
// Create some Lists/Maps we're going to need
List<String> posts = new List<String>();
Map<String, PostModel> postMap = new Map<String, PostModel>();
Map<String, bool> likeMap = new Map<String, bool>();
// Convienience/Brevity
final List<DocumentSnapshot> documents = results.documents;
final int numDocs = documents.length;
if (numDocs > 0) {
final firstDoc = results.documents[0].data;
final lastDoc = results.documents[numDocs-1].data;
// Get all your likes for a certain date range that aligns with the
// documents we just retrieved
likeMap = await getLikes(firstDoc['postCreated'], lastDoc['postCreated']);
}
// Loop through, and create all the PostModels
for (int i = 0; i < numDocs; i++) {
DocumentSnapshot doc = documents[i];
PostModel post = snapshotToPostModel(doc, likeMap[doc.documentID]);
postMap[doc.documentID] = post;
posts.add(post.key);
}
final Map<String, dynamic> res = new Map<String, dynamic>();
res['posts'] = posts;
res['postMap'] = postMap;
return res;
}