【问题标题】:Trying to load the data as I scroll my listview滚动列表视图时尝试加载数据
【发布时间】:2021-08-11 07:45:28
【问题描述】:

我试图让页面在滚动时加载数据,所以我在列表构建器中创建了一个滚动监听器,然后我在未来的构建器中创建了一个获取下一个函数。

但是我如何调用 fetchNext 函数,该函数在我的未来构建器中调用我的 void scrollListener() {}。

这样对数据进行分页是否正确。请帮忙。

这是列表生成器


class PostGridScreen extends StatefulWidget {
  final String type, city, state;
  PostGridScreen({this.type, this.city, this.state});

  @override
  _PostGridScreenState createState() => _PostGridScreenState();
}

class _PostGridScreenState extends State<PostGridScreen>
    with AutomaticKeepAliveClientMixin {
  Future _getPosts;
  int documentLimit = 5;
  bool _hasNext = true;
  bool _isFetchingUsers = false;
  final _usersSnapshot = <DocumentSnapshot>[];
  final scrollController = ScrollController();

  var refreshKey = GlobalKey<RefreshIndicatorState>();
  @override
  void initState() {
    _fetchPosts();
    // scrollController.addListener(scrollListener);
    super.initState();
  }

  @override
  void dispose() {
    scrollController.dispose();
    super.dispose();
  }

   void scrollListener() {}

  Future _fetchPosts() {
    return _getPosts = Provider.of<BaseProvider>(context, listen: false)
        .getPosts(widget.type, widget.city, widget.state, documentLimit);
  }

  Future<Null> refreshList() async {
    refreshKey.currentState?.show(atTop: false);
    await Future.delayed(Duration(seconds: 2));

    setState(() {
      _fetchPosts();
    });

    return null;
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);

    return RefreshIndicator(
      onRefresh: () => refreshList(),
      child: FutureBuilder(
          key: PageStorageKey('Page1'),
          future: _getPosts,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.done) {
              return ListView.builder(
                controller: scrollController,
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
//Fetch Next

                  Future fetchNextUsers() async {
                    if (_isFetchingUsers) return;
                    _isFetchingUsers = true;
                    try {
                      _getPosts =
                          Provider.of<BaseProvider>(context, listen: false)
                              .getPosts(
                                  widget.type,
                                  widget.city,
                                  widget.state,
                                  documentLimit,
                                  startAfter: _usersSnapshot.isNotEmpty
                                      ? _usersSnapshot.last
                                      : null);
                      _usersSnapshot.addAll(snapshot.data);
                      if (snapshot.data.length < documentLimit)
                        _hasNext = false;
                    } catch (e) {}
                    _isFetchingUsers = false;
                  }

//Tile

                  return GestureDetector(
                    onTap: () {
                      Navigator.of(context).push(MaterialPageRoute(
                        builder: (context) => PostDetailScreen(
                          post: snapshot.data[index],
                        ),
                      ));
                    },
                    child: Padding(
                      padding: EdgeInsets.only(
                        top: 10,
                        bottom: 3.0,
                        right: 20.0,
                        left: 20.0,
                      ),
                      child: Container(
                        decoration: BoxDecoration(
                          boxShadow: [
                            BoxShadow(
                              color: Colors.black12,
                              offset: const Offset(
                                5.0,
                                5.0,
                              ),
                              blurRadius: 10.0,
                              spreadRadius: 2.0,
                            ), //BoxShadow
                          ],
                          color: Colors.blue,
                          borderRadius: BorderRadius.circular(20.0),
                          image: DecorationImage(
                            image: NetworkImage(
                              snapshot.data[index]["imageUrl"],
                            ),
                            fit: BoxFit.cover,
                          ),
                        ),
                        height: 190.0,
                        width: 100,
                      ),
                    ),
                  );
                },
              );
            } else {
              return Center(
                child: Text("Loading..."),
              );
            }
          }),
    );
  }

  @override
  bool get wantKeepAlive => true;
}

这是基础提供者

class BaseProvider with ChangeNotifier {

  final CollectionReference postsCollection =
      FirebaseFirestore.instance.collection("posts");


  //Fetching Data
  Future getPosts(String type, String city, String state, int limit,
      {DocumentSnapshot startAfter}) async {
    try {
      if (startAfter == null) {
        QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore
            .instance
            .collection("posts")
            .where('type', isEqualTo: type)
            .where('sellercity', isEqualTo: city)
            .where('sellerstate', isEqualTo: state)
            .limit(limit)
            .get();
        return response.docs;
      } else {
        QuerySnapshot<Map<String, dynamic>> response = await FirebaseFirestore
            .instance
            .collection("posts")
            .where('type', isEqualTo: type)
            .where('sellercity', isEqualTo: city)
            .where('sellerstate', isEqualTo: state)
            .startAfterDocument(startAfter)
            .limit(limit)
            .get();
        return response.docs;
      }
    } catch (e) {
      print(e.toString());
      return e;
    }
  }
 
}

【问题讨论】:

标签: firebase flutter google-cloud-firestore


【解决方案1】:

如果我理解正确,您希望您的应用不会立即加载和呈现列表中的所有内容,而是及时呈现它们,从而将其显示给用户。 为了实现这一点,您必须实现延迟加载,ListView.builder 完全自行完成,因此您无需担心

【讨论】:

  • 不不,我不想那样。我想在滚动屏幕时从 firebase 加载数据,这样我可以使用更少的读取。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 2013-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多