Paginaton is the process of separating print or digital content into discrete pages.

Why do you need it on your mobile app?
- it allows to reduce data loading time, therefore provides smoother UX and reduces server load.
- it just saves battery and network traffic.
It’s fair to say that pagination is not just “nice to have”, it is a required technique in the mobile app or a web app development, if it has to be dealing with a significant amount of data.
to implement pagination make sure that API response support pagination
, so first part of pagination should implemented in Backend Side
Adjusting the limit
you are changing a number of items per "page", and modifying an offset
(in some API variations also called skip
) you are "jumping" between pages. (this in Backend side)
in flutter side
you can handle pagination manually or using a package
Manually
you can manually handle pagination by using NotificationListener of type ScrollNotification
- define scroll controller
ScrollController scrollController = new ScrollController();
2. create a ListView and passing scroll controller to ListView’s controller
ListView(
physics: BouncingScrollPhysics(),
itemCount: 4,
controller: scrollController,
itemBuilder: (BuildContext context, int index) {})
3. wraaping ListView with NotificationListener of type ScrollNotification
NotificationListener<ScrollNotification>(
onNotification: (scrollNotification) {
if (scrollNotification is ScrollEndNotification) {
//call api for the next page
}
return true;
},
child:ListView())
the most important part is :
if (scrollNotification is ScrollEndNotification) {
//call api for the next page
}
this listen to scrolling if hit the last pixel of the screen :)
this manual implementation for pagination made with Laravel
with nextPageUrl param everytime you hit the end of screen you check for nextPage if not null make api call to get the new Data
listner(BuildContext context) async {
if (bookPagination != null) {
if (bookPagination!.nextPageUrl != null) {
print("---------------LOAD MORE---------------");
// _loadMore = true;
notifyListeners();
API
.getMoreBookings(getStorage.read('uid'),
bookPagination!.nextPageUrl!, getStorage.read('token'))
.then((value) {
if (!value.error) {
bookPagination= value.data!;
notifyListeners();
_updateBookings(value.data!.data);
}else {
_setState(ViewState.Error);
_setErrorWidget(getErrorType(value.statusCode!));
}
});
}
}
_updateBooking function where i put code to add more data to a List
List<Data> _bookings = [];
let hit back to widget or UI side
how to show the progress indicator in the end of list while waiting for a new data
make itemCount of listView equal to your data length plus 1
ListView(
physics: BouncingScrollPhysics(),
itemCount: dataList.length()+1 ,
)
and in the ListView itemBuilder make if condition to check if the current index is the last
if (index == model.bookings.length) {
return indicator(); //progressIndicator
}
of course you must be sure of structure of your API response ,
before implementing paging in flutter.
this is the manual way
Paging with a package:
this package used to make paging in you app
it is very simple
basic example
class CharacterListView extends StatefulWidget {
@override
_CharacterListViewState createState() => _CharacterListViewState();
}
class _CharacterListViewState extends State<CharacterListView> {
static const _pageSize = 20; // items per page
final PagingController<int, CharacterSummary> _pagingController =
PagingController(firstPageKey: 0); //scroll controller
@override
void initState() {
_pagingController.addPageRequestListener((pageKey) {
//pageKey is current page
//pageKey is of type Num so you have to convert it to INT
_fetchPage(pageKey.toInt());
});
super.initState();
}
//api call
Future<void> _fetchPage(int pageKey) async {
try {
final newItems = await RemoteApi.getCharacterList(pageKey, _pageSize);
final isLastPage = newItems.length < _pageSize;
if (isLastPage) {
_pagingController.appendLastPage(newItems);
} else {
final nextPageKey = pageKey + newItems.length;
_pagingController.appendPage(newItems, nextPageKey);
}
} catch (error) {
_pagingController.error = error;
}
}
@override
Widget build(BuildContext context) =>
// Don't worry about displaying progress or error indicators on screen; the
// package takes care of that. If you want to customize them, use the
// [PagedChildBuilderDelegate] properties.
PagedListView<int, CharacterSummary>(
pagingController: _pagingController,
builderDelegate: PagedChildBuilderDelegate<CharacterSummary>(
itemBuilder: (context, item, index) => CharacterListItem(
character: item,
),
),
);
@override
void dispose() {
_pagingController.dispose();
super.dispose();
}
}
that’s it:)
thanks for reading