
Large lists can slow down Flutter applications because loading thousands of records at once consumes memory and affects performance.
Infinite scrolling with pagination solves this problem by loading data in small chunks as users scroll.
In this tutorial, we will learn how to implement pagination in Flutter using ListView.builder and ScrollController.
What is Pagination in Flutter?
Pagination means loading data page by page instead of fetching everything at once.
Example:
Page 1 → Load 20 items
User scrolls ↓
Page 2 → Load next 20 items
User scrolls ↓
Page 3 → Load more items
Common use cases:
- Social media feeds
- Product listings
- News apps
- Chat applications
Step 1: Create Flutter Project
flutter create pagination_demo
Step 2: Create Sample API Function
In real apps, this data comes from an API. Here we simulate a network request:
Future<List<String>> fetchItems(int page) async {
await Future.delayed(
const Duration(seconds: 1),
);
return List.generate(
20,
(index) => "Item ${page * 20 + index}",
);
}
Step 3: Add Pagination Variables
Create variables to manage data loading:
final ScrollController controller = ScrollController();
List<String> items = [];
int currentPage = 0;
bool isLoading = false;
Step 4: Detect Scroll End
Use ScrollController to detect when the user reaches the bottom.
controller.addListener(() {
if(controller.position.pixels ==
controller.position.maxScrollExtent) {
loadMore();
}
});
Step 5: Load More Data
Create a function to fetch the next page.
Future<void> loadMore() async {
if(isLoading) return;
setState(() {
isLoading = true;
});
final data = await fetchItems(currentPage);
setState(() {
items.addAll(data);
currentPage++;
isLoading = false;
});
}
The isLoading check prevents multiple API calls while loading.
Step 6: Display Data with ListView.builder
ListView.builder(
controller: controller,
itemCount: items.length + 1,
itemBuilder: (context, index) {
if(index == items.length) {
return isLoading
? const CircularProgressIndicator()
: const SizedBox();
}
return ListTile(
title: Text(items[index]),
);
},
)
The extra list item displays a loading indicator when fetching more data.
Step 7: Dispose Controller
Always dispose controllers to avoid memory leaks.
@override
void dispose() {
controller.dispose();
super.dispose();
}
Pagination Best Practices
✅ Load data in small chunks
✅ Show loading indicators
✅ Handle API errors
✅ Prevent duplicate requests
✅ Dispose controllers properly
Flutter Pagination Packages
For large production apps, you can use:
infinite_scroll_paginationflutter_blocriverpod
These packages simplify complex pagination workflows.
Conclusion
Infinite scrolling is an important Flutter technique for building fast and scalable applications.
Using ScrollController and ListView.builder, you can easily create smooth feeds, product lists, and data-driven apps without loading everything at once.
Mastering pagination helps you build Flutter apps with better performance and user experience.
SDK Flutter: https://github.com/v-modal/vmodal_sdk_flutter
SDK Android: https://github.com/v-modal/vmodal_sdk_android
Discord: https://discord.gg/K72z28KUx

Top comments (0)