riverpod_pagination 0.1.0
riverpod_pagination: ^0.1.0 copied to clipboard
A simple and effective pagination solution for Flutter apps using Riverpod state management.
riverpod_pagination #
A simple and effective pagination solution for Flutter apps using Riverpod state management.
Features #
- π Multiple pagination strategies: Token-based, offset-based, and page number-based pagination
- π― Easy to use: Simple API with sensible defaults
- π§ Highly customizable: Customize loading states, error handling, and UI components
- π± ListView and GridView support: Built-in widgets for both list and grid layouts
- β»οΈ Automatic retry logic: Built-in error handling with configurable retry attempts
- π¨ Material Design 3: Modern default widgets following Material Design guidelines
- π Pull-to-refresh: Built-in refresh functionality
- β‘ Performance optimized: Efficient scroll detection and state management
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
riverpod_pagination: ^0.1.0
flutter_riverpod: ^2.4.0
Quick Start #
1. Create your data model #
class User {
final int id;
final String name;
final String email;
const User({required this.id, required this.name, required this.email});
}
2. Extend PaginatedNotifier #
class UsersNotifier extends PaginatedNotifier<User> {
final ApiService _apiService = ApiService();
UsersNotifier() : super(
config: const PaginationConfig(pageSize: 20),
strategy: PaginationStrategy.token,
);
@override
Future<PaginationResult<User>> fetchPage(PaginationParams params) async {
if (params is TokenPaginationParams) {
return await _apiService.getUsers(
nextPageToken: params.nextPageToken,
limit: params.limit,
);
}
throw ArgumentError('Invalid pagination params');
}
}
3. Create your provider #
final usersProvider = StateNotifierProvider<UsersNotifier, DefaultPaginatedState<User>>(
(ref) => UsersNotifier(),
);
4. Use PaginatedListView in your widget #
class UsersScreen extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final notifier = ref.read(usersProvider.notifier);
return Scaffold(
body: PaginatedListView<User, DefaultPaginatedState<User>>(
provider: usersProvider,
itemBuilder: (context, user, index) => ListTile(
title: Text(user.name),
subtitle: Text(user.email),
),
onLoad: () => notifier.loadFirstPage(),
onLoadMore: (token) => notifier.loadMore(),
onRefresh: () => notifier.refresh(),
),
);
}
}
Pagination Strategies #
Token-based Pagination (Cursor-based) #
Best for APIs that return a next page token or cursor:
class TokenNotifier extends PaginatedNotifier<Item> {
TokenNotifier() : super(strategy: PaginationStrategy.token);
@override
Future<PaginationResult<Item>> fetchPage(PaginationParams params) async {
final tokenParams = params as TokenPaginationParams;
return await api.getItems(
nextPageToken: tokenParams.nextPageToken,
limit: tokenParams.limit,
);
}
}
Offset-based Pagination #
Best for APIs that use skip/take or offset/limit parameters:
class OffsetNotifier extends PaginatedNotifier<Item> {
OffsetNotifier() : super(strategy: PaginationStrategy.offset);
@override
Future<PaginationResult<Item>> fetchPage(PaginationParams params) async {
final offsetParams = params as OffsetPaginationParams;
return await api.getItems(
offset: offsetParams.offset,
limit: offsetParams.limit,
);
}
}
Page Number-based Pagination #
Best for APIs that use page numbers:
class PageNotifier extends PaginatedNotifier<Item> {
PageNotifier() : super(strategy: PaginationStrategy.pageNumber);
@override
Future<PaginationResult<Item>> fetchPage(PaginationParams params) async {
final pageParams = params as PageNumberPaginationParams;
return await api.getItems(
page: pageParams.page,
pageSize: pageParams.pageSize,
);
}
}
Grid View Support #
Use PaginatedGridView for grid layouts:
PaginatedGridView<Photo, DefaultPaginatedState<Photo>>.count(
provider: photosProvider,
crossAxisCount: 2,
itemBuilder: (context, photo, index) => PhotoCard(photo: photo),
onLoad: () => notifier.loadFirstPage(),
onLoadMore: (token) => notifier.loadMore(),
onRefresh: () => notifier.refresh(),
)
Configuration Options #
Customize pagination behavior with PaginationConfig:
PaginatedNotifier(
config: const PaginationConfig(
pageSize: 30, // Items per page
scrollThreshold: 0.8, // When to trigger load more (80% scrolled)
autoLoad: true, // Auto-load first page
maxRetries: 3, // Retry failed requests
retryDelay: Duration(seconds: 1), // Delay between retries
),
strategy: PaginationStrategy.token,
)
Custom Widgets #
Customize loading states and error handling:
PaginatedListView(
provider: itemsProvider,
itemBuilder: (context, item, index) => ItemCard(item: item),
loadingWidget: CustomLoadingWidget(),
errorWidget: (error, retry) => CustomErrorWidget(
error: error,
onRetry: retry,
),
emptyWidget: CustomEmptyWidget(),
loadingMoreWidget: CustomLoadingMoreWidget(),
// ... other callbacks
)
Advanced Usage #
Custom State Management #
Implement your own state class:
class CustomPaginatedState implements PaginatedState<Item> {
// Implement required methods
@override
final List<Item> items;
@override
final bool isLoading;
// ... other required properties
}
Error Handling #
Handle specific errors in your notifier:
@override
Future<PaginationResult<Item>> fetchPage(PaginationParams params) async {
try {
return await api.getItems(params);
} on NetworkException catch (e) {
throw 'Network error: Please check your connection';
} on AuthException catch (e) {
throw 'Authentication failed: Please log in again';
}
}
Examples #
Check out the example directory for complete working examples:
- Users List: Token-based pagination with user profiles
- Posts List: Offset-based pagination with article cards
- Photos Grid: Page number-based pagination with image grid
To run the examples:
cd example
flutter run
API Reference #
PaginatedNotifier #
Base class for pagination logic.
Constructor Parameters:
config: Pagination configuration optionsstrategy: Pagination strategy (token, offset, or pageNumber)
Methods:
loadFirstPage(): Load the initial pageloadMore(): Load the next pagerefresh(): Refresh from the beginning
PaginatedListView<T, S> #
Widget for paginated list views.
Required Parameters:
provider: Riverpod provider containing paginated stateitemBuilder: Function to build each list itemonLoad: Callback for initial loadonLoadMore: Callback for loading more itemsonRefresh: Callback for refresh
PaginatedGridView<T, S> #
Widget for paginated grid views with the same API as PaginatedListView plus grid-specific options.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
License #
This project is licensed under the MIT License - see the LICENSE file for details.