A library for widgets that load their content one page (or batch) at a time (also known as lazy-loading and pagination).
Features
- Load data one page at a time
- Retry failed pages
- Override the default loading, retry, and error widgets if desired
- Manage loading of data more closely using a
PagewiseLoadController
- ListView and GridView implementations
- SliverList and SliverGrid implementations
- Extendability using inheritance
Breaking Change Starting V1.0.0:
The library has been rewritten in version 1.0.0 to provide a more efficient implementation that does not require a totalCount
parameter and shows only one loading sign when users scroll down. In addition, a new parameter has been added to itemBuilder
callback to provide
the index if needed by the user.
Installing the library:
Like any other package, add the library to your pubspec.yaml dependencies:
dependencies:
flutter_pagewise:
Then import it wherever you want to use it:
import 'package:flutter_pagewise/flutter_pagewise.dart';
Using the library
The library provides the following widgets:
-
PagewiseGridView
: A pagewise implementation of GridView. It could be
used as follows:PagewiseGridView.count( pageSize: 10, crossAxisCount: 2, mainAxisSpacing: 8.0, crossAxisSpacing: 8.0, childAspectRatio: 0.555, padding: EdgeInsets.all(15.0), itemBuilder: (context, entry, index) { // return a widget that displays the entry's data }, pageFuture: (pageIndex) { // return a Future that resolves to a list containing the page's data }, );
-
PagewiseListView
: A pagewise implementation of ListView. It could be
used as follows:PagewiseListView( pageSize: 10, padding: EdgeInsets.all(15.0), itemBuilder: (context, entry, index) { // return a widget that displays the entry's data }, pageFuture: (pageIndex) { // return a Future that resolves to a list containing the page's data } );
-
PagewiseSliverGrid
: A pagewise implementation of SliverGrid. It could be used similar toPagewiseGridView
for cases where a sliver is needed. -
PagewiseSliverList
: A pagewise implementation of SliverList. It could be used similar toPagewiseListView
for cases where a sliver is needed.
The classes provide all the properties of ListViews
and GridViews
. In addition, you must provide the itemBuilder
, which tells Pagewise how you want to render each element, and pageFuture
, which Pagewise calls to fetch new pages. Please note that pageFuture
must not return more values than mentioned in the pageSize
parameter.
Customizing the widget:
In addition to the required parameters, Pagewise provides you with optional parameters to customize the widget. You have loadingBuilder
, errorBuilder
, noItemsFoundBuilder
, and retryBuilder
to customize the widgets that show on loading, error, no found items and retry respectively.
The loadingBuilder
can be used as follows:
loadingBuilder: (context) {
return Text('Loading...');
}
The noItemsFoundBuilder
can be used as follows:
noItemsFoundBuilder: (context) {
return Text('No Items Found');
}
The retryBuilder
can be used as follows:
retryBuilder: (context, callback) {
return RaisedButton(
child: Text('Retry'),
onPressed: () => callback()
);
}
Thus, the retryBuilder
provides you with a callback that you can call when you want to retry.
The errorBuilder
is only relevant when showRetry
is set to false
, because, otherwise, the retryBuilder
is shown instead. The errorBuilder
can be used as follows:
errorBuilder: (context, error) {
return Text('Error: $error');
}
Check the classes’ documentation for more details.
Providing your own PagewiseLoadController:
Pagewise widgets manage the loading of pages using a PagewiseLoadController
. This controller is responsible for fetching data, handling errors, etc.
You don’t have to provide a controller yourself when creating a Pagewise widget. The widget will create one for you. However you might wish to create one yourself in order to achieve some effects.
Notice though that if you provide a controller yourself, you should provide the [pageFuture] and [pageSize] parameters to the controller instead of the widget.
A possible use case of the controller is to force a reset of the loaded pages using a RefreshIndicator. you could achieve that as follows (note that we added the Future.value({})
as a dummy return value, because onRefresh
expects a Future
, but reset
does not return one):
final _pageLoadController = PagewiseLoadController(
pageSize: 6,
pageFuture: BackendService.getPage
);
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () async {
this._pageLoadController.reset();
await Future.value({});
},
child: PagewiseListView(
itemBuilder: this._itemBuilder,
pageLoadController: this._pageLoadController,
),
);
}
Another use case for creating the controller yourself is if you want to listen to the state of Pagewise and act accordingly. For example, you might want to show a snackbar when we reach the end of the list In that case, you could do:
final _pageLoadController = PagewiseLoadController(
pageSize: 6,
pageFuture: BackendService.getPage
);
@override
void initState() {
super.initState();
this._pageLoadController.addListener(() {
if (!this._pageLoadController.hasMoreItems) {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text('No More Items!')
)
);
}
});
}
Creating your own Pagewise Widgets:
You need to inherit from the Pagewise
class. Check the code of PagewiseListView
and PagewiseGridView
for examples
Source Code
Please Visit Flutter Lazy Loading Source Code at GitHub