I m new to flutter, and I'm trying to paginate a chat when scroll reach top with streambuilder. The problem is: when i make the query in scrollListener streambuilder priorize his query above the scrollListener and returns de old response. Is there any way to do this? What are my options here? Thanks!
Class ChatScreenState
In initState I create the scroll listener.
@override
void initState() {
listScrollController = ScrollController();
listScrollController.addListener(_scrollListener);
super.initState();
}
Here i create the StreamBuilder with the query limited to 20 last messages. Using the _messagesSnapshots as global List.
@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]);
},
);
}
And in the _scollListener method i query the next 20 messages and add the result to the Global list.
_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"),
));
}
}