Flutter - Infinite Scroll Pagination
Last Updated :
28 Apr, 2025
Infinite lists are a way to display paginated data efficiently. When a user scrolls to the end of the current page, more data is fetched and added to the list. This is also known as endless scrolling pagination, infinite scrolling pagination, auto-pagination, lazy loading pagination, and progressive loading pagination. It is good because it loads data only when the user interacts with the list. When data in the list is bigger it is better to use this widget for the app's performance optimizations and Interactive UI for Users.
What Will We Make?
We will create a user list with his/her name and email address. We get these data from Punk API. We will call an API Call to get data from it. A sample video is given below to get an idea about what we are going to do in this article.
Step By Step Implementation
Step 1: Create a New Project in Android Studio
To set up Flutter Development on Android Studio please refer to Android Studio Setup for Flutter Development, and then create a new project in Android Studio please refer to Creating a Simple Application in Flutter.
Step 2: Add Package in your pubspec.yaml file
Dart
dependencies:
infinite_scroll_pagination: ^4.0.0
Step 3: Import the library in your page
Dart
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
Step 4: Add Controllers and page size
Pagination Controllers is controller to manage the data refresh it,add page listeners
Dart
final int _pageSize = 20;
final PagingController<int, dynamic> _pagingController =
PagingController(firstPageKey: 1);
Step 5: Add API Request and get data
To get the data from sample API we will use http package
Dart
class RemoteApi {
static Future<List<dynamic>?> getBeerList(
// Page means on which page you are currently
int page,
// Limit per page you want to set
int limit,
) async {
try {
// Request the API on url
final response = await http.get(
Uri.parse(
'https://api.punkapi.com/v2/beers?'
'page=$page'
'&per_page=$limit',
),
);
if (response.statusCode == 200) {
// Decode the response
final mybody = jsonDecode(response.body);
return mybody;
}
} catch (e) {
print("Error $e");
}
return null;
}
}
Step 6: Update the API data in controllers and add listener to it
We create a function which will add the data in page controller
Dart
Future<void> _fetchPage(int pageKey) async {
try {
// get api /beers list from pages
final newItems = await RemoteApi.getBeerList(pageKey, _pageSize);
// Check if it is last page
final isLastPage = newItems!.length < _pageSize;
// If it is last page then append
// last page else append new page
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
// Appending new page when it is not last page
final nextPageKey = pageKey + 1;
_pagingController.appendPage(newItems, nextPageKey);
}
}
// Handle error in catch
catch (error) {
print(_pagingController.error);
// Sets the error in controller
_pagingController.error = error;
}
}
We will add a listener in init state to call the previous function whenver user go to next page or when more data is required to load
Dart
@override
void initState() {
_pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
super.initState();
}
Step 7: We will add UI in body to show infinite scroll page view
Now we will add a paged listview in our screens
Dart
Scaffold(
// Page Listview with divider as a separation
body: PagedListView<int, dynamic>.separated(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<dynamic>(
animateTransitions: true,
itemBuilder: (_, item, index) => ListTile(
leading: CircleAvatar(
radius: 20,
backgroundImage: NetworkImage(item["image_url"]),
),
title: Text(item["name"]),
),
),
separatorBuilder: (_, index) => const Divider(),
),
)
Step 8: Dispose the Controller
Dart
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
Step 9: Refresh the listview on pulling down
Dart
// Refrsh Indicator pull down
RefreshIndicator(
onRefresh: () => Future.sync(
// Refresh through page controllers
() => _pagingController.refresh(),
),child:...)
You are good to go!!!
Additional Tips
We have used the listview seperated here to show the data. You can use different widget available in
- GridView: A widget for creating a scrollable grid layout of items.
- SliverGrid: Similar to GridView, but used within a CustomScrollView for more advanced scrolling effects.
- ListView: Displays a scrollable list of widgets in a single column.
- SliverList: A list within a CustomScrollView for dynamic and optimized scrolling.
- Custom Layout: Custome layout as per you requirement
In all this option seperated constructor is also available
Complete Source Code
Dart
class InfiniteScrollExample extends StatefulWidget {
const InfiniteScrollExample({super.key});
@override
State<InfiniteScrollExample> createState() => _InfiniteScrollExampleState();
}
class _InfiniteScrollExampleState extends State<InfiniteScrollExample> {
final int _pageSize = 20;
final PagingController<int, dynamic> _pagingController =
PagingController(firstPageKey: 1);
@override
void initState() {
_pagingController.addPageRequestListener((pageKey) {
_fetchPage(pageKey);
});
super.initState();
}
Future<void> _fetchPage(int pageKey) async {
try {
// get api /beers list from pages
final newItems = await RemoteApi.getBeerList(pageKey, _pageSize);
// Check if it is last page
final isLastPage = newItems!.length < _pageSize;
// If it is last page then append last page else append new page
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
// Appending new page when it is not last page
final nextPageKey = pageKey + 1;
_pagingController.appendPage(newItems, nextPageKey);
}
}
// Handle error in catch
catch (error) {
print(_pagingController.error);
// Sets the error in controller
_pagingController.error = error;
}
}
@override
Widget build(BuildContext context) =>
// Refrsh Indicator pull down
RefreshIndicator(
onRefresh: () => Future.sync(
// Refresh through page controllers
() => _pagingController.refresh(),
),
child: Scaffold(
appBar: AppBar(
title: const Text("Pagination Scroll Flutter Template"),
),
// Page Listview with divider as a separation
body: PagedListView<int, dynamic>.separated(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<dynamic>(
animateTransitions: true,
itemBuilder: (_, item, index) => ListTile(
leading: CircleAvatar(
radius: 20,
backgroundImage: NetworkImage(item["image_url"]),
),
title: Text(item["name"]),
),
),
separatorBuilder: (_, index) => const Divider(),
),
),
);
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
}
class RemoteApi {
static Future<List<dynamic>?> getBeerList(
// Page means on which page you are currently
int page,
// Limit per page you want to set
int limit,
) async {
try {
// Request the API on url
final response = await http.get(
Uri.parse(
'https://api.punkapi.com/v2/beers?'
'page=$page'
'&per_page=$limit',
),
);
if (response.statusCode == 200) {
// Decode the response
final mybody = jsonDecode(response.body);
return mybody;
}
} catch (e) {
print("Error $e");
}
return null;
}
}
Output:
Similar Reads
Non-linear Components In electrical circuits, Non-linear Components are electronic devices that need an external power source to operate actively. Non-Linear Components are those that are changed with respect to the voltage and current. Elements that do not follow ohm's law are called Non-linear Components. Non-linear Co
11 min read
Steady State Response In this article, we are going to discuss the steady-state response. We will see what is steady state response in Time domain analysis. We will then discuss some of the standard test signals used in finding the response of a response. We also discuss the first-order response for different signals. We
9 min read
Use Case Diagram - Unified Modeling Language (UML) A Use Case Diagram in Unified Modeling Language (UML) is a visual representation that illustrates the interactions between users (actors) and a system. It captures the functional requirements of a system, showing how different users engage with various use cases, or specific functionalities, within
9 min read
Half Wave Rectifier A Half-wave rectifier is an electronic device that is used to convert Alternating current (AC) to Direct current (DC). A half-wave rectifier allows either a positive or negative half-cycle of AC to pass and blocks the other half-cycle. Half-wave rectifier selectively allows only one half-cycle of th
15 min read
Flutter Tutorial This Flutter Tutorial is specifically designed for beginners and experienced professionals. It covers both the basics and advanced concepts of the Flutter framework.Flutter is Googleâs mobile SDK that builds native Android and iOS apps from a single codebase. It was developed in December 2017. When
7 min read
What is Agile Methodology? The Agile methodology is a proper way of managing the project with breaking them into smaller phases which is iteration. It basically focus on flexibility of the project which we can change and improve the team work regularly as per requirements.Table of ContentWhat is Agile?What is the Agile Method
14 min read
How to Download and Install the Google Play Store The Google Play Store is the heartbeat of your Android experienceâhome to millions of apps, games, and updates that keep your device functional, fun, and secure. But what if your phone or tablet doesnât have it pre-installed?In this step-by-step guide, youâll learn how to safely download and install
6 min read
Top 8 Software Development Life Cycle (SDLC) Models used in Industry Software development models are various processes or methods that are chosen for project development depending on the objectives and goals of the project. Many development life cycle models have been developed to achieve various essential objectives. Models specify the various steps of the process a
9 min read
IEEE 802.11 Architecture The IEEE 802.11 standard, commonly known as Wi-Fi, outlines the architecture and defines the MAC and physical layer specifications for wireless LANs (WLANs). Wi-Fi uses high-frequency radio waves instead of cables for connecting the devices in LAN. Given the mobility of WLAN nodes, they can move unr
9 min read
Schmitt Trigger We use Schmitt Triggers in digital electronics. It is used for rejecting the noise from the input signals by using the hysteresis curve. To provide accurate and more stable results, it uses two threshold voltages i.e., upper threshold voltage (VUT) and lower threshold voltage (VLT). It is mainly use
11 min read