请尝试以下代码:
class ProductList extends StatefulWidget { @override _ProductListState createState() => _ProductListState();}class _ProductListState extends State<ProductList> { StreamController<List<documentSnapshot>> _streamController = StreamController<List<documentSnapshot>>(); List<documentSnapshot> _products = []; bool _isRequesting = false; bool _isFinish = false; void onChangeData(List<documentChange> documentChanges) { var isChange = false; documentChanges.forEach((productChange) { if (productChange.type == documentChangeType.removed) { _products.removeWhere((product) { return productChange.document.documentID == product.documentID; }); isChange = true; } else { if (productChange.type == documentChangeType.modified) { int indexWhere = _products.indexWhere((product) { return productChange.document.documentID == product.documentID; }); if (indexWhere >= 0) { _products[indexWhere] = productChange.document; } isChange = true; } } }); if(isChange) { _streamController.add(_products); } } @override void initState() { Firestore.instance .collection('products') .snapshots() .listen((data) => onChangeData(data.documentChanges)); requestNextPage(); super.initState(); } @override void dispose() { _streamController.close(); super.dispose(); } @override Widget build(BuildContext context) { return NotificationListener<ScrollNotification>( onNotification: (ScrollNotification scrollInfo) { if (scrollInfo.metrics.maxScrollExtent == scrollInfo.metrics.pixels) { requestNextPage(); } return true; }, child: StreamBuilder<List<documentSnapshot>>( stream: _streamController.stream, builder: (BuildContext context, AsyncSnapshot<List<documentSnapshot>> snapshot) { if (snapshot.hasError) return new Text('Error: ${snapshot.error}'); switch (snapshot.connectionState) { case ConnectionState.waiting: return new Text('Loading...'); default: log("Items: " + snapshot.data.length.toString()); return ListView.separated( separatorBuilder: (context, index) => Divider( color: Colors.black, ), itemCount: snapshot.data.length, itemBuilder: (context, index) => Padding( padding: const EdgeInsets.symmetric(vertical: 32), child: new ListTile(title: new Text(snapshot.data[index]['name']),subtitle: new Text(snapshot.data[index]['description']), ), ), ); } }, )); } void requestNextPage() async { if (!_isRequesting && !_isFinish) { QuerySnapshot querySnapshot; _isRequesting = true; if (_products.isEmpty) { querySnapshot = await Firestore.instance .collection('products') .orderBy('index') .limit(5) .getdocuments(); } else { querySnapshot = await Firestore.instance .collection('products') .orderBy('index') .startAfterdocument(_products[_products.length - 1]) .limit(5) .getdocuments(); } if (querySnapshot != null) { int oldSize = _products.length; _products.addAll(querySnapshot.documents); int newSize = _products.length; if (oldSize != newSize) { _streamController.add(_products); } else { _isFinish = true; } } _isRequesting = false; } }}产品项的JSON:
{ "index": 1, "name": "Pork", "description": "Thịt heo/lợn"}链接Github示例: https : //github.com/simplesoft-
duongdt3/flutter_firestore_paging



