Infinite Scrolling Pagination in Flutter

Learn how to implement infinite scrolling pagination (also known as lazy loading) in Flutter using the Infinite Scroll Pagination package. By Edson Bueno.

Leave a rating/review
Download materials
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Creating a Builder Delegate

For the final touch, fill that same gap in code by specifying this new parameter to your PagedListView, in the same level as pagingController, padding and separatorBuilder:

builderDelegate: PagedChildBuilderDelegate<Article>(
  itemBuilder: (context, article, index) => ArticleListItem(
    article: article,
  ),
  firstPageErrorIndicatorBuilder: (context) => ErrorIndicator(
    error: _pagingController.error,
    onTryAgain: () => _pagingController.refresh(),
  ),
  noItemsFoundIndicatorBuilder: (context) => EmptyListIndicator(),
),

PagedChildBuilderDelegate is a collection of builders for every widget involved in infinite scrolling pagination.

Although you’ve only specified three parameters in your code, knowing all seven of them might save you in the future:

  • itemBuilder: This builds your list items. It’s the only required parameter; all others have defaults.
  • firstPageErrorIndicatorBuilder: This builds a widget that informs the user the occurrence of an error fetching the first page. In this scenario, you won’t yet have any list items loaded, so you’ll want this widget to fill the entire space. Make sure you call refresh() on your controller if you decide to add a retry button to your indicator — take another look at the previous code snippet and you’ll see it.
  • newPageErrorIndicatorBuilder: This also indicates an error, but for subsequent page requests. As you already have some items loaded, the widget you build here appears at the bottom of your list. If you add a retry button to your indicator, make sure you call retryLastRequest() on your controller when the user taps your button.
  • firstPageProgressIndicatorBuilder: This builds the widget that’ll show while loading the first page. You won’t yet have any items loaded, so you’ll want this widget to fill the entire space.
  • newPageProgressIndicatorBuilder: This is similar to the previous builder, but it shows while loading subsequent pages. As you already have some items loaded, the widget you build here appears at the bottom of your list.
  • noItemsFoundIndicatorBuilder: What if your API successfully returns an empty list? Technically that’s not an error, and it’s usually associated with too many filter options selected. The widget you build here covers this “zero items” scenario.
  • noMoreItemsIndicatorBuilder: Here it is, the gold at the end of the rainbow! This is where you optionally build a widget to display when the user finally reaches the end of your list. Mystery solved!

Build and run. Try turning off your device’s connection and using swipe to refresh as shown in the GIF below. This will help you test both RefreshIndicator and the custom error indicator widget.

Sample project with filters not working properly.

Hmm, there’s a bug in your app. Apparently that wasn’t the final touch after all. Try figuring out what’s wrong. If you’re stuck, click the Reveal button below to find out what it is.

[spoiler title=”Filters Bug”]
Applying filters doesn’t seem to be taking any effect.
[/spoiler]

Applying Filters

You know what they say: Be suspicious if your code works on the first try. Well, yours didn’t, so you’re probably doing something right!

Here’s what’s causing the bug: When the user applies filters, ArticleListScreen rebuilds your PagedArticleListView with a brand-new ListPreferences, but no one warned your PagingController about the change.

The place for solving this is lib/ui/list/paged_article_list_view.dart. Inside _PagedArticleListViewState, add the following function override:

@override
void didUpdateWidget(PagedArticleListView oldWidget) {
  if (oldWidget.listPreferences != widget.listPreferences) {
    _pagingController.refresh();
  }
  super.didUpdateWidget(oldWidget);
}

This is what the code above is saying: Whenever the widget associated with this State subclass updates, if the listPreferences also changed, refresh the _pagingController by calling refresh() on it.

Mission accomplished. Time to build and run readwenderlich for the last time and allow the wonder of infinite scrolling pagination to amaze you. You did it!

Completed sample project.

Where to Go From Here?

Download the completed project files by clicking the Download Materials button at the top or bottom of the tutorial.

Now for the coolest part: The Infinite Scroll Pagination package comes with replacement parts for your middle piece. Choose whichever suits your next layout the best.

All classes from the Infinite Scroll Pagination package represented as jigsaw puzzle pieces.

You can find more details on these extra pieces in the package’s cookbook.

Here’s a suggestion: The endpoint you used to fetch your articles accepts search queries. How about using that to add search support to readwenderlich?

We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!