Last updated:
0 purchases
paginated live list
A package that handles pagination, subscriptions to updates, updating pages, and error handling.
Getting Started #
The package provides a set of widgets that takes a concrete PaginationController and implement a live list behavior by controlling loading of items when needed, subscriptions to pages updates, updating the list and notifying the view.
Specifying the view itself is up to the programmer.
There is also a fully featured PaginatedLiveList widget that uses the basic set of widgets but with the view being a ListView.
For usage example see the example directory.
Installation #
Add paginated_live_list as a dependency to your project pubspec.yaml and run flutter pub get to install all your dependencies.
# in pubspec.yaml
dependencies:
paginated_live_list:
copied to clipboard
Basic Concepts #
The Page Cursor #
Every page has its own cursor that serves as a pointer for loading the next page. The cursor used to load the first page is null since it has no preceding pages. It's up to the developer to define a concrete PageCursor.
class IntPageCursor implements PageCursor {
final int nextPage;
IntPageCursor(this.nextPage);
}
copied to clipboard
The Page Class #
Contains the list of items in the page, a cursor defined by the developer, and a boolean isLastPage to indicate whether or not there is more pages to load.
Usage #
Import The Package #
import 'package:paginated_live_list/paginated_live_list.dart';
copied to clipboard
Define Your Items Class #
Item class needs to be immutable and implement the equality operator
class Item {
final String id;
final DateTime createdAt;
Item({
required this.id,
required this.createdAt,
});
@override
int get hashCode => id.hashCode;
@override
bool operator ==(Object? other) {
if (other is Item && id == other.id) {
return true;
} else {
return false;
}
}
}
copied to clipboard
Implement a PageCursor #
You must implement the equality operator.
class CustomPageCursor implements PageCursor {
final String? lastItemId;
CustomPageCursor(this.lastItemId);
@override
int get hashCode => lastItemId.hashCode;
@override
bool operator ==(Object other) {
if (identical(this, other)) {
return true;
} else if (other is! CustomPageCursor) {
return false;
}
return lastItemId == other.lastItemId;
}
}
copied to clipboard
Implement a PaginationController #
Extend the PaginationController and implement
PaginationController.comparePagesOrder: for Page ordering.
It should simply determine the order of the two pages passed in as parameters using the cursors of the pages or their items.
@override
int comparePagesOrder(Page<Item> page, Page<Item> other) {
// Assuming the pages are in ascending order.
// for descending order multiply by -1.
return page.items.last.createdAt.compareTo(other.items.last.createdAt);
}
copied to clipboard
PaginationController.updateCursorOfAdjustedPage: for adjustment of page cursors.
Adjustment is needed when a page changes it's cursor due to an update. The adjustment allows the PaginationController to maintain the current pages by not having to reload all the pages after the page that changed it's cursor.
@override
Page<Offer> updateCursorOfAdjustedPage(Page<Item> page) {
final last = page.items.last;
return Page(
page.items,
CustomPageCursor(last.id, last.createdAt),
page.isLastPage);
}
copied to clipboard
PaginationController.onLoadPage: for loading new pages.
This should provide a stream for a page that emits the page then each time the page is updated. All kinds of updates are supported: Updating an item(s), deleting an item(s), and adding a new item(s).
@override
Stream<Page<T>> onLoadPage(CustomPageCursor cursor) {
return dataSource.list(after: cursor.lastItemId, size: 10).map((items) =>
Page(items, CustomPageCursor(items.lastOrNull?.id), items.length < 10));
}
copied to clipboard
Define the View #
If you want to have a ListView, you may use the LivePaginatedList widget.
Widget build(BuildContext context) {
return PaginationControllerProvider<Offer>(
create: (context) => CustomPaginationController(),
child: PaginatedLiveList<Offer>(
controller: null,
itemBuilder: (context, state, index) {
final item = state.items[index];
return ItemWidget(item: item);
},
),
);
}
copied to clipboard
For other scroll views (e.g. GridView) you need to use the basic widgets. Namely, the PaginationBehavior, the ViewBuilder. See the LivePaginatedList widget implementation for an example.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.