我想知道如何改进以下代码以使其更高效并获得有关添加/丢弃内容的提示。在当前的实现中,我将所有产品存储在 _data 列表中,它是一个 DocumentSnapshot 对象列表,代表从数据库中检索到的产品。我觉得这样效率很低。
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:shopping_cs308_project/models/product_model.dart';
class ProductsList extends StatefulWidget {
const ProductsList({super.key});
@override
ProductsListState createState() => ProductsListState();
}
class ProductsListState extends State<ProductsList> {
final FirebaseFirestore _db = FirebaseFirestore.instance;
late Query _query;
late ScrollController _scrollController;
final List<DocumentSnapshot> _data = [];
bool _isLoading = false;
bool _hasMoreData = true;
@override
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_scrollListener);
_query =
_db.collection('products').orderBy('date', descending: true).limit(10);
_loadMoreData();
}
void _scrollListener() {
if (_scrollController.offset >=
_scrollController.position.maxScrollExtent &&
!_scrollController.position.outOfRange) {
_loadMoreData();
}
}
Future<void> _loadMoreData() async {
if (!_hasMoreData || _isLoading) return;
_isLoading = true;
final lastVisible = _data.isNotEmpty ? _data.last : null;
Query query = _query;
if (lastVisible != null) {
query = query.startAfterDocument(lastVisible);
}
final querySnapshot =
await query.get(const GetOptions(source: Source.server));
final newData = querySnapshot.docs;
setState(() {
_data.addAll(newData);
_hasMoreData = newData.length == 10;
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
controller: _scrollController,
itemCount: _data.length + (_hasMoreData ? 1 : 0),
itemBuilder: (context, index) {
if (index == _data.length) {
return _buildLoader();
} else {
final product = ProductModel.fromJson(
_data[index].data() as Map<String, dynamic>);
return ListTile(
title: Text(product.title),
subtitle: Text(product.description),
trailing: Text('\$${product.price}'),
);
}
},
),
);
}
Widget _buildLoader() {
return _isLoading
? const Padding(
padding: EdgeInsets.all(16.0),
child: Center(child: CircularProgressIndicator()),
)
: Container();
}
}