【发布时间】:2019-05-29 23:23:11
【问题描述】:
我是 Flutter 的新手,我正在尝试在使用 streambuilder 滚动到顶部时对聊天进行分页。问题是:当我在 scrollListener 中进行查询时,streambuilder 将他的查询优先于 scrollListener 并返回旧响应。有没有办法做到这一点?我在这里有什么选择?谢谢!
类 ChatScreenState
在 initState 中我创建了滚动监听器。
@override
void initState() {
listScrollController = ScrollController();
listScrollController.addListener(_scrollListener);
super.initState();
}
在这里,我创建了 StreamBuilder,查询限制为 20 条最后的消息。使用 _messagesSnapshots 作为全局列表。
@override
Widget build(BuildContext context) {
return Scaffold(
key: key,
appBar: AppBar(title: Text("Chat")),
body: Container(
child: Column(
children: <Widget>[
Flexible(
child: StreamBuilder<QuerySnapshot>(
stream: Firestore.instance
.collection('messages')
.where('room_id', isEqualTo: _roomID)
.orderBy('timestamp', descending: true)
.limit(20)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) return LinearProgressIndicator();
_messagesSnapshots = snapshot.data.documents;
return _buildList(context, _messagesSnapshots);
},
)),
Divider(height: 1.0),
Container(
decoration: BoxDecoration(color: Theme.of(context).cardColor),
child: _buildTextComposer(),
),
],
),
));
}
Widget _buildList(BuildContext context, List<DocumentSnapshot> snapshot) {
_messagesSnapshots = snapshot;
return ListView.builder(
controller: listScrollController,
itemCount: _messagesSnapshots.length,
reverse: true,
itemBuilder: (context, index) {
return _buildListItem(context, _messagesSnapshots[index]);
},
);
}
在 _scollListener 方法中,我查询接下来的 20 条消息并将结果添加到全局列表中。
_scrollListener() {
// If reach top
if (listScrollController.offset >=
listScrollController.position.maxScrollExtent &&
!listScrollController.position.outOfRange) {
// Then search last message
final message = Message.fromSnapshot(
_messagesSnapshots[_messagesSnapshots.length - 1]);
// And get the next 20 messages from database
Firestore.instance
.collection('messages')
.where('room_id', isEqualTo: _roomID)
.where('timestamp', isLessThan: message.timestamp)
.orderBy('timestamp', descending: true)
.limit(20)
.getDocuments()
.then((snapshot) {
// To save in the global list
setState(() {
_messagesSnapshots.addAll(snapshot.documents);
});
});
// debug snackbar
key.currentState.showSnackBar(new SnackBar(
content: new Text("Top Reached"),
));
}
}
【问题讨论】:
-
解决方案好运吗?
-
@Purus 查看这个 github 项目。工作正常 github.com/simplesoft-duongdt3/flutter_firestore_paging
标签: firebase pagination dart flutter google-cloud-firestore