easy_infinite_pagination 0.0.6 easy_infinite_pagination: ^0.0.6 copied to clipboard
The Easy Infinite Pagination package provides a simple and customizable way to implement infinite pagination in your Flutter applications.
Easy Infinite Pagination #
A simple and customizable infinite pagination package for Flutter applications. The Easy Infinite Pagination package makes it easy to add infinite pagination to your apps. With just a few lines of code, you can create beautiful and efficient paginated lists, grids, and page views.
Features #
-
Easy to use: This package is designed to function similarly to standard Flutter widgets like ListView, without the need for additional controllers. Unlike many other packages, which often require custom controllers, you can think of
easy_infinite_pagination
as an enhanced version ofListView
,GridView
, andPageView
. -
Customizable:: You can customize the appearance of the pagination indicators as you like, Include
firstPageLoading
,firstPageError
,firstPageNoItemsFound
,loadMoreLoading
,loadMoreError
, andloadMoreReachedLastPage
. -
Supports list view, grid view, and page view layouts: The package can be used to create infinite lists, infinite grids, and infinite page views.
-
Works with any state management: The package is designed to work with any state management such as
Bloc
,Riverpod
,Provider
and even thesetState
. -
Efficient: The package uses a number of optimizations to ensure that it is efficient, even for large datasets.
-
Extensible: The package can be extended to support custom pagination scenarios for example suppose that you want to add pagination for flutter_staggered_grid_view you can do that by wrapping your widget with
PaginationLayoutBuilder
see Support Custom Pagination Layouts.
Getting started #
Import the following package in your dart file
import 'package:easy_infinite_pagination/easy_infinite_pagination.dart';
Usage #
class SimpleExample extends StatefulWidget {
const SimpleExample({super.key});
@override
State<SimpleExample> createState() => _SimpleExampleState();
}
class _SimpleExampleState extends State<SimpleExample> {
List<String> _items = [];
bool _isLoading = true;
void _fetchData() async {
setState(() {
_isLoading = true;
});
await Future.delayed(const Duration(seconds: 3));
setState(() {
_isLoading = false;
// Add 20 more items to the list. This could be a network request, a database query, etc.
_items = List.generate(_items.length + 20, (i) => 'Item ${i + 1}');
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Simple Example'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: InfiniteListView(
delegate: PaginationDelegate(
itemCount: _items.length,
itemBuilder: (_, index) => ListTile(
title: Text(_items[index]),
),
isLoading: _isLoading,
onFetchData: _fetchData,
),
),
);
}
}
Layouts Supported by easy_infinite_pagination
#
Layout | Easy Infinite Pagination |
---|---|
ListView.builder | InfiniteListView |
ListView.separated | InfiniteListView.separated |
SliverList.builder | SliverInfiniteListView |
SliverList.separated | SliverInfiniteListView.separated |
SliverFixedExtentList | SliverInfiniteListView (just provide itemExtent parameter) |
SliverPrototypeExtentList | SliverInfiniteListView (just provide prototypeItem parameter) |
GridView.builder | InfiniteGridView |
SliverGrid.builder | SliverInfiniteGridView |
PageView.builder | InfinitePageView |
PaginationLayoutBuilder
: for custom pagination layouts scenarios
Customizable Indicators #
- With
easy_infinite_pagination
you can customize the appearance of the pagination indicators as you like. IncludefirstPageLoading
,firstPageError
,firstPageNoItemsFound
,loadMoreLoading
,loadMoreError
, andloadMoreReachedLastPage
. - see full example custom indicators example.
InfiniteListView(
delegate: PaginationDelegate(
itemCount: _items.length,
itemBuilder: (context, index) => ListTile(
title: DefaultListTile(index: index),
),
isLoading: _isLoading,
onFetchData: _fetchData,
firstPageLoadingBuilder: (context) =>
const FirstPageLoadingIndicator(),
firstPageErrorBuilder: (context, onRetry) => FirstPageErrorIndicator(
onRetry: onRetry,
),
firstPageNoItemsBuilder: (context) =>
const FirstPageNoItemsFoundedIndicator(),
loadMoreLoadingBuilder: (context) => const LoadMoreLoadingIndicator(),
loadMoreErrorBuilder: (context, onRetry) => LoadMoreErrorIndicator(
onRetry: onRetry,
),
loadMoreNoMoreItemsBuilder: (context) =>
const LoadMoreNoMoreItemsIndicator(),
),
),
Control when to fetch data #
- With
easy_infinite_pagination
you can control when to fetch data. by using theinvisibleItemsThreshold
parameter andfetchDataOnStart
parameter. invisibleItemsThreshold
is used as a threshold to determine when to fetch more data default value is 3.fetchDataOnStart
is used to determine whether to fetch data on start or not default value is true.
InfiniteListView(
delegate: PaginationDelegate(
// The number of remaining invisible items that should trigger a new fetch.
// The default value is 3.
invisibleItemsThreshold: 5,
// If true, it will fetch data on start.
fetchDataOnStart: true,
....
),
)
How to use easy_infinite_pagination
with Bloc #
- The
easy_infinite_pagination
package is designed to work with any state management such asBloc
,Riverpod
,Provider
and even thesetState
. - see full example bloc example.
InfiniteListView.separated(
delegate: PaginationDelegate(
isLoading: state is PostsFetchLoading,
hasError: state is PostsFetchError,
hasReachedMax: context.read<PostsListCubit>().hasReachedMax,
// The number of remaining invisible items that should trigger a new fetch.
// The default value is 3.
invisibleItemsThreshold: 5,
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return PostWidget(post: post);
},
// here we add a custom error screen if the state is an error state.
// and this screen will be shown if an error occurs while fetching data for the first page.
firstPageErrorBuilder: state is PostsFetchError
? (context, onRetry) =>
CustomErrorScreen(errorMessage: state.message, onRetry: onRetry)
: null,
// this method will be called when the user reaches the end of the list or for the first page.
onFetchData: () async {
await context.read<PostsListCubit>().fetchPosts();
},
),
separatorBuilder: (context, index) => const Divider(),
)
How to use easy_infinite_pagination
with Sliver
#
- The package supports
sliver
layouts such asSliverInfiniteListView
,SliverInfiniteListView.separated
andSliverInfiniteGridView
. - see full example sliver grid view example.
SliverPadding(
padding: const EdgeInsets.all(16.0),
sliver: SliverInfiniteGridView(
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
),
delegate: PaginationDelegate(
isLoading: state.isLoading,
hasError: state.hasError,
hasReachedMax: state.hasReachedMax,
// The number of remaining invisible items that should trigger a new fetch.
// The default value is 3.
invisibleItemsThreshold: 5,
itemCount: state.posts.length,
itemBuilder: (context, index) {
final post = state.posts[index];
return PostGridWidget(post: post);
},
// this method will be called when the user reaches the end of the list or for the first page.
onFetchData: () async {
await context.read<PostsGridCubit>().fetchPosts();
},
),
),
)
How to use InfinitePageView
#
- The package supports
InfinitePageView
. - see full example page view example.
InfinitePageView(
scrollDirection: Axis.vertical,
delegate: PaginationDelegate(
itemCount: _items.length,
itemBuilder: (_, index) => ListTile(
title: PageViewItem(index: index),
),
isLoading: _isLoading,
invisibleItemsThreshold: 1,
onFetchData: _fetchData,
),
),
Support Searching, Sorting and Filtering with easy_infinite_pagination
#
- Absolutely you can use
easy_infinite_pagination
package to support searching, sorting and filtering. The optimal approach depends on your state management.
Support Custom Pagination Layouts #
- To create a new sliver layout, if
InfiniteListView
,SliverInfiniteListView
,InfiniteGridView
,SliverInfiniteGridView
, andInfinitePageView
do not meet your requirements, witheasy_infinite_pagination
you can make your own pagination layout. - For example suppose that you want to add pagination for flutter_staggered_grid_view you can do that by wrapping your widget with
PaginationLayoutBuilder
. - see full example custom pagination example.
return PaginationLayoutBuilder(
// Provider the layout strategy (box or sliver).
// In this case we used the box strategy.
// because the child not sliver widget.
layoutStrategy: LayoutStrategy.box,
delegate: paginationDelegate,
useShrinkWrapForFirstPageIndicators: _useShrinkWrapForFirstPageIndicators,
layoutChildBuilder: (
context,
itemBuilder,
itemCount,
bottomLoaderBuilder,
) =>
MasonryGridView.custom(
gridDelegate: gridDelegate,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
padding: padding,
// Here we create a predefined sliver delegate by the package
// this delegate is used to handle the bottom loader widget while loading, success and error state.
childrenDelegate: PaginationLayoutBuilder.createSliverChildDelegate(
builder: itemBuilder,
childCount: itemCount,
bottomLoaderBuilder: bottomLoaderBuilder,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
),
)
Additional information #
- Contributing: Contributions to the Easy Infinite Pagination package are welcome! GitHub repository.
- Filing issues: If you encounter any issues with the Easy Infinite Pagination package, please file an issue on the GitHub repository.
- Support: If you have any questions or need help using the Easy Infinite Pagination package, please feel free to reach out to the package authors on GitHub.
We hope you find the Easy Infinite Pagination package helpful!