how to do pagination in GridView (Flutter)

2020-07-13 08:47发布

I want to implement pagination in GridView I use GridView.builder I want to download 10 by 10 items when the user reaches the last row

4条回答
三岁会撩人
2楼-- · 2020-07-13 09:22

I also needed this but couldn't find any widget for the gridview pagination, so I tried to make a component based on @Mazin Ibrahim's answer below. It seems to be working but not sure if it is the right way to do this.

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(),
    );
  }
}

Example -

GridViewPagination(
          itemCount: 10,
          childAspectRatio: 1,
          itemBuilder: _buildGridItem,
          onNextPage: (int nextPage) {
            return fetchData();
          },
        )
查看更多
Explosion°爆炸
3楼-- · 2020-07-13 09:25

You can use this plugin here: Paging. Wrap your GridView inside of it and tell me if this works!

查看更多
够拽才男人
4楼-- · 2020-07-13 09:33

You can do this using a NotificationListener. As a simple demonstration it will increase the length of your GridView whenever it reaches end of page :

    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
                    }
                ),
    );
查看更多
Rolldiameter
5楼-- · 2020-07-13 09:39

create a Scroll controller

ScrollController _scrollController = new ScrollController();

add a scroll event listener

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

Now just need to set the controller in your GridView, ListViewand ...

GridView.builder(
     controller: _scrollController,
));
查看更多
登录 后发表回答