How to get an infinite scroll with ListView from Firestore with Flutter
Ok, after looking on the net I found a way to resolve this issue thanks to this link
I write here the complete code if someone needs:
class AudioScreenList extends StatefulWidget {
@override
_AudioScreenListState createState() => _AudioScreenListState();
}
class _AudioScreenListState extends State<AudioScreenList> {
bool isPerformingRequest = false;
static const String _collectionRussian = 'speech-ru';
static const String _loadingTextRussian = 'Loading...';
static const String _speechTitle = 'speechTitle';
static const String _speechSubtitle = 'speechSubtitle';
static const String _audioLink = 'audioLink';
static const String _pastorCode = 'pastorCode';
static const String _pastorName = 'pastorName';
static const String _id = "id";
@override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: Firestore.instance
.collection(_collectionRussian)
.orderBy(_id, descending: true)
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData)
return const Center(
child: Text(
_loadingTextRussian,
style: TextStyle(fontSize: 25.0, color: Colors.grey),
));
return ListView(children: getExpenseItems(snapshot));
}));
}
getExpenseItems(AsyncSnapshot<QuerySnapshot> snapshot) {
return snapshot.data.documents
.map((doc) => new Container(
margin: const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 0.0),
child: ListTile(
leading: Padding(
padding: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0),
child: Hero(
tag: doc[_audioLink],
child: new ClipOval(
child: Container(
width: 70.0,
height: 70.0,
child: Image.asset(
Utils.getImagePastor(doc[_pastorCode]),
fit: BoxFit.cover,
),
)))),
title: new Text(doc[_speechTitle]),
subtitle: new Text(doc[_speechSubtitle].toString() +
" - " +
doc[_pastorName].toString()),
onTap: () => onPressed(context, doc[_speechTitle],
doc[_pastorCode], doc[_audioLink]))))
.toList();
}
onPressed(BuildContext context, String speechTitle, String pastorCode,
String audioLink) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ScreenAudioSelected(speechTitle, pastorCode, audioLink)));
}
}
Singorenko
Updated on December 09, 2022Comments
-
Singorenko over 1 year
I'm working with Firestore and ListView in Flutter. Every works fine for some items in the list, but I scroll down farther than the seen limits, I got many messages: "the method was called on null". Seems that the ListView.builder is not handling correctly all the date request from the Firebase or something like it.
This is the code:
import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:father_home_flutter/screen_audio_selected.dart'; import 'package:father_home_flutter/model/utils.dart'; class AudioScreenList extends StatelessWidget { static const String _collectionRussian = 'speech-ru'; static const String _loadingTextRussian = 'Loading...'; static const String _speechTitle = 'speechTitle'; static const String _speechSubtitle = 'speechSubtitle'; static const String _audioLink = 'audioLink'; static const String _pastorCode = 'pastorCode'; static const String _pastorName = 'pastorName'; static const String _id = "id"; @override Widget build(BuildContext context) { return Scaffold( body: StreamBuilder( stream: Firestore.instance .collection(_collectionRussian) .limit(100) .orderBy(_id, descending: true) .snapshots(), builder: (context, snapshot) { if (!snapshot.hasData) return const Center( child: Text( _loadingTextRussian, style: TextStyle(fontSize: 25.0, color: Colors.grey), )); return ListView.builder( itemCount: snapshot.data.documents.length, itemBuilder: (BuildContext context, int i) => _buildRow(context, snapshot.data.documents[i]), ); })); } Widget _buildRow(BuildContext context, DocumentSnapshot document) { return Container( margin: const EdgeInsets.fromLTRB(0.0, 8.0, 0.0, 0.0), height: 90.0, child: ListTile( leading: Padding( padding: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0), child: Hero( tag: document[_audioLink], child: new ClipOval( child: Container( width: 70.0, height: 70.0, child: Image.asset( Utils.getImagePastor(document[_pastorCode]), fit: BoxFit.cover, ), )))), title: Text(document[_speechTitle]), subtitle: Text(document[_speechSubtitle] + " - " + document[_pastorName]), onTap: () => onPressed(context, document[_speechTitle], document[_pastorCode], document[_audioLink]))); } onPressed(BuildContext context, String speechTitle, String pastorCode, String audioLink) { Navigator.push( context, MaterialPageRoute( builder: (context) => ScreenAudioSelected(speechTitle, pastorCode, audioLink))); } }
and this is the problem on the simulator:
I was looking around the web for ways how to handle it, but I just found examples where simulate the server request like this example https://flutter-academy.com/flutter-listview-infinite-scrolling/
Anyone had face the same problem or has an idea about how to solve it?.