如何高效地从 firestore 中获取数据并显示给用户

问题描述 投票:0回答:0

我想知道如何改进以下代码以使其更高效并获得有关添加/丢弃内容的提示。在当前的实现中,我将所有产品存储在 _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();
  }
}

flutter firebase google-cloud-firestore lazy-loading
© www.soinside.com 2019 - 2024. All rights reserved.