如何在列表视图的滚动中添加更多项目?
Posted
技术标签:
【中文标题】如何在列表视图的滚动中添加更多项目?【英文标题】:How do i add more items on scroll in the listview? 【发布时间】:2020-08-03 18:09:57 【问题描述】:此代码当前加载存储在 Firestore 集合中的所有 brews。我如何才能加载最初仅 10 个 brews,然后当用户向下滚动并到达 10 个 brews 列表的末尾时。它应该在最后一次 brew 之后再加载 10 个。并且 brews 应该根据时间戳进行排序。
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);
【问题讨论】:
首先您只想获取 10 个项目? 它可能是 20..但是我想在滚动上加载更多.. ***.com/a/60315739/2252830 非常感谢..但是你能不能把它简化一下..我只是这里的初学者,这看起来有点复杂..@pskink 你有一个完整的工作小部件,只需使用它 【参考方案1】:您可以使用滚动控制器和侦听器来确定用户是否已滚动到屏幕底部。如果他们已经从数据库服务加载接下来的 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.
);
【讨论】:
Future> 获取 brews async QuerySnapshot 快照 = await brewsCollection .orderBy('timestamp', descending: true).getDocuments();返回 _brewListFromSnapshot(快照); 这就是我获取当前列表的方式..我已经添加了 scrollController ..你可以告诉我我需要在这里添加的功能吗? 你的意思是如何一次从 Firestore 中获取 10 个项目? 最初使用上面的代码..它会加载列表中的所有 brews..但我最初只想加载 10 个 brews,然后当用户到达最初加载的 10 个 brews 列表的末尾时..我想再加载10个等等.. 这与如何使用某种查询对存储在 Firestore 中的数据进行分页有关。我看到你之前已经问过这个问题并得到了合理的回答。 ***.com/a/61133438/5211220 基本上,您需要能够编写查询以获取 10 个块的文档。如果您在文档上有一个自动递增的整数属性,您可以按该属性排序,然后最初选择该属性在 0 和 11 之间的位置.然后在 10 到 21 等之间的第二个查询。【参考方案2】:不确定以下是否会有所帮助,但这是我在我的颤振应用程序中所做的。特别注意底部的_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());
我认为你需要的是 startAfterDocument。见下文...
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;
【讨论】:
这不能回答我的问题,但感谢您的努力..我正在尝试找出如何订购下一组数据,它startsAfter()最后一组数据是最初加载到屏幕上。 @alex 我明白了。我编辑了我的答案以包含实际查询 firestore 的代码。我想你可能需要startAftrerDocument
。旁注:我感觉到你的痛苦。 dart/flutter 中的 firebase 文档不是很好。祝你好运!
如果我的编辑成功了,我稍后会回来并让我的回复更简洁地回答您的问题。
是的,我需要 startAfterDocument 让我试试看这是否可行..但它很有帮助,所以我会对此表示赞成..以上是关于如何在列表视图的滚动中添加更多项目?的主要内容,如果未能解决你的问题,请参考以下文章
如何实现在动态布局中添加更多视图在android中实现滚动视图