Pagination in Flutter using Pageview.builder

Viewed 3480

I'm trying to implement pagination but I can't find any examples of how I should create the controller Listener function - or where I should put it. Please advise. Let me know if I should add more info too.

Currently, my listener function looks like this:

(within initState)
    pagecontroller.addListener(() {
      print(pagecontroller.page);
      if (pagecontroller.page == _postslist.length-1) {
        fetchMore();
      }
    });

What happens currently is that the function is only called once, and subsequently never called later on.

2 Answers

I don't know if this problem still exists (it's been six months since you've asked), but since this question still doesn't have an answer that is marked as correct I'll try.

If I understand correctly you want to load more items into your PageView once you've reached the last item of your PageView. You don't need a listener in your initState for that. You can just check if you've reached the last item in onPageChanged and then load more items.

It should work like this:

PageView.builder(
                      controller: _pageController,
                      itemCount: _items.length,
                      onPageChanged: (i) {
                        
                        if (i == _items.length - 1) {
                         getMoreItems().then((value) {
                            setState(() {
                              _items= value;
                            });
                          });
                        }
                      },
)

I guess you are trying to listen to pageController to get the currentPage. If that's the case, you should fire an event using the PageController by using its methods (animateToPage, jumpToPage, nextPage, previousPage), so that it can evoke your listener.

I assume my page transitions are handled by the PageView.builder

You can find the PageView.builder description in the documentation like this:

This constructor is appropriate for page views with a large (or infinite) number of children because the builder is called only for those children that are actually visible.

So it supports you in building the screens efficiently in case of large number of pages. You'll still need to handle navigation between pages on your own.

The link I've included above has an example you can refer to in terms of PageController usage. I'll include it here for convenience:

class MyPageView extends StatefulWidget {
  MyPageView({
    Key key
  }): super(key: key);

  _MyPageViewState createState() => _MyPageViewState();
}

class _MyPageViewState extends State < MyPageView > {
  PageController _pageController;

  @override
  void initState() {
    super.initState();
    _pageController = PageController();
  }

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: PageView(
          controller: _pageController,
          children: [
            Container(
              color: Colors.red,
              child: Center(
                child: RaisedButton(
                  color: Colors.white,
                  onPressed: () {
                    if (_pageController.hasClients) {
                      _pageController.animateToPage(
                        1,
                        duration: const Duration(milliseconds: 400),
                          curve: Curves.easeInOut,
                      );
                    }
                  },
                  child: Text('Next'),
                ),
              ),
            ),
            Container(
              color: Colors.blue,
              child: Center(
                child: RaisedButton(
                  color: Colors.white,
                  onPressed: () {
                    if (_pageController.hasClients) {
                      _pageController.animateToPage(
                        0,
                        duration: const Duration(milliseconds: 400),
                          curve: Curves.easeInOut,
                      );
                    }
                  },
                  child: Text('Previous'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
Related