简体   繁体   中英

how to do pagination in GridView (Flutter)

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

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

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

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

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 , ListView and ...

GridView.builder(
     controller: _scrollController,
));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM