你好,我正在尝试在列表中使用分页。并且列表数据来自firebase。我不确定如何使用流构建器对数据进行分页。现在我通过在didChangeDependencies()函数中调用getdocuments来进行分页。但是添加新数据后,列表不会更新。如果有人可以提供帮助,那对我来说太好了。这是我现在正在做的..
didChangeDependencies() { super.didChangeDependencies(); getProducts(); _scrollController.addListener(() { double maxScroll = _scrollController.position.maxScrollExtent; double currentScroll = _scrollController.position.pixels; double delta = MediaQuery.of(context).size.height * 0.20; if (maxScroll - currentScroll <= delta) { getProducts(); } }); } getProducts() async { if (!hasMore) { return; } if (isLoading) { return; } setState(() { isLoading = true; }); QuerySnapshot querySnapshot; if (lastDocument == null) { querySnapshot = await firestore .collection('products') .limit(documentLimit) .orderBy('timestamp', descending: true) .getDocuments(); } else { querySnapshot = await firestore .collection('products') .startAfterDocument(lastDocument) .limit(documentLimit) .orderBy('timestamp', descending: true) .getDocuments(); } if (querySnapshot.documents.length < documentLimit) { hasMore = false; } if (querySnapshot.documents.isNotEmpty) { lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1]; products.addAll(querySnapshot.documents); setState(() { isLoading = false; }); } }
请尝试以下代码:
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