【问题标题】:how to do pagination in GridView (Flutter)如何在 GridView (Flutter) 中进行分页
【发布时间】:2019-05-27 09:30:15
【问题描述】:

我想在 GridView 中实现分页我使用 GridView.builder 我想在用户到达最后一行时下载 10 x 10 个项目

【问题讨论】:

  • 你能分享一下你到目前为止做了什么吗?
  • 当我需要一种对行列数据进行分页的方法时,我只使用了 Grid 并在其中绑定了数据
  • 从文档中你必须使用 IndexedWidgetBuilder 来按需构建孩子:api.flutter.dev/flutter/widgets/ListView-class.html
  • 好的,我会试试的

标签: flutter dart flutter-layout


【解决方案1】:

您可以使用NotificationListener 执行此操作。作为一个简单的演示,它会在您到达页面末尾时增加GridView 的长度:

    var items_number = 10 ;

    return NotificationListener<ScrollNotification>(
         onNotification: (scrollNotification){
              if(scrollNotification.metrics.pixels == scrollNotification.metrics.maxScrollExtent){
                 setState(() {
                    items_number += 10 ;
                 });    
              }
         },
         child: GridView.builder(
                    itemCount: items_number,
                    itemBuilder: (context, index) {
                      //.... the reminder of your code
                    }
                ),
    );

【讨论】:

  • 对我来说很棒,但我想用来自 API 的数据来做这件事,如果可能的话,如何制作加载器并等待数据
  • 然后用StreamBuilder 包裹NotificationListener 并让流从onNotification() 函数中改变。
【解决方案2】:

创建一个滚动控制器

ScrollController _scrollController = new ScrollController();

添加滚动事件监听器

@override
  void initState() {
    super.initState();
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        // Bottom poistion
      }
    });
  }

现在只需要在你的GridViewListView和...中设置控制器。

GridView.builder(
     controller: _scrollController,
));

【讨论】:

    【解决方案3】:

    我也需要这个,但找不到gridview pagination 的任何小部件,所以我尝试根据@Mazin Ibrahim 下面的回答制作一个组件。它似乎正在工作,但不确定这是否是正确的方法。

    typedef Future<bool> OnNextPage(int nextPage);
    
    class GridViewPagination extends StatefulWidget {
      final int itemCount;
      final double childAspectRatio;
      final OnNextPage onNextPage;
      final Function(BuildContext context, int position) itemBuilder;
      final Widget Function(BuildContext context) progressBuilder;
    
      GridViewPagination({
        this.itemCount,
        this.childAspectRatio,
        this.itemBuilder,
        this.onNextPage,
        this.progressBuilder,
      });
    
      @override
      _GridViewPaginationState createState() => _GridViewPaginationState();
    }
    
    class _GridViewPaginationState extends State<GridViewPagination> {
      int currentPage = 1;
      bool isLoading = false;
    
      @override
      Widget build(BuildContext context) {
        return NotificationListener<ScrollNotification>(
          onNotification: (ScrollNotification sn) {
            if (!isLoading && sn is ScrollUpdateNotification && sn.metrics.pixels == sn.metrics.maxScrollExtent) {
              setState(() {
                this.isLoading = true;
              });
              widget.onNextPage?.call(currentPage++)?.then((bool isLoaded) {
                setState(() {
                  this.isLoading = false;
                });
              });
            }
            return true;
          },
          child: CustomScrollView(
            slivers: <Widget>[
              SliverGrid(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisSpacing: 1,
                  mainAxisSpacing: 1,
                  crossAxisCount: 2,
                  childAspectRatio: widget.childAspectRatio,
                ),
                delegate: SliverChildBuilderDelegate(
                  widget.itemBuilder,
                  childCount: widget.itemCount,
                  addAutomaticKeepAlives: true,
                  addRepaintBoundaries: true,
                  addSemanticIndexes: true,
                ),
              ),
              if (isLoading)
                SliverToBoxAdapter(
                  child: widget.progressBuilder?.call(context) ?? _defaultLoading(),
                ),
            ],
          ),
        );
      }
    
      Widget _defaultLoading() {
        return Container(
          padding: EdgeInsets.all(15),
          alignment: Alignment.center,
          child: CircularProgressIndicator(),
        );
      }
    }
    

    示例 -

    GridViewPagination(
              itemCount: 10,
              childAspectRatio: 1,
              itemBuilder: _buildGridItem,
              onNextPage: (int nextPage) {
                return fetchData();
              },
            )
    

    【讨论】:

    • 我在我的项目中使用了这个,但我面临一个问题,每当我到达最后它重新加载并再次滚动回网格顶部,你有什么解决方案吗?
    【解决方案4】:

    您可以在此处使用此插件:Paging。将您的 GridView 包裹在其中并告诉我这是否有效!

    【讨论】:

      猜你喜欢
      • 2017-04-13
      • 2012-01-04
      • 1970-01-01
      • 2013-04-29
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多