📜 listview_utils
Superchange ListView
with custom adapters to add infinite scrolling.
Example
CustomListView(
loadingBuilder: CustomListLoading.defaultBuilder,
itemBuilder: (context, index, item) {
return ListTile(
title: Text(item['title']),
);
},
adapter: NetworkListAdapter(
url: 'https://jsonplaceholder.typicode.com/posts',
limitParam: '_limit',
offsetParam: '_start',
),
);
Migration guide from 0.1.X to 0.2.Y
children
property removed
If you want to use children property with CustomListView
, I suggest you to use flutter's own ListView
component instead. We wanted to focus on dynamic sources rather than static ones.
onErrorBuilder
property type changed
Old | New |
---|---|
|
|
onLoadMore
property deprecated
You need to convert custom data source handlers to list adapters. Here's simple example how to implement your own list adapter.
class MyListAdapter implements BaseListAdapter {
const MyListAdapter(this.url);
final String url;
@override
Future<ListItems> getItems(int offset, int limit) async {
// To handle errors using `errorBuilder` you need to not use *try/catch* block.
final response = await http.get(`url?_offset=$offset&_limit=$limit`);
final data = jsonDecode(response.data);
return ListItems(data, reachedToEnd: data.length == 0);
}
@override
bool shouldUpdate(MyListAdapter old) {
return old.url != url;
}
}
Getting Started
Add those lines to pubspec.yaml
file and run flutter pub get
.
dependencies:
listview_utils: ">=0.2.2 <2.0.0"
Check out Installing tab for more details.
Import listview_utils package to your application by adding this line:
import 'package:listview_utils/listview_utils.dart';
This will import required classes to use listview_utils.
Properties
CustomListView(
// Items fetched per request (default: 30)
pageSize: 30,
// Header widget (default: null)
header: Container(...),
// Footer widget (default: null)
footer: Container(...),
// The widget that displayed if the list is empty (default: null)
empty: Text('List is empty'),
// Item provider adapter (default: null)
adapter: ListAdapter(
fetchItems: (int offset, int limit) {
return ListItems([ ... ]);
},
),
//Pagination Mode [offset/page] (default: offset)
paginationMode: PaginationMode.offset
//Initial offset (default: 0)
initialOffset: 0
// A callback function to build list items (required)
itemBuilder: (BuildContext context, int index, dynamic item) {
// If items provided by adapter the `item` argument will be matching element
return ListTile(
title: Text(item['title']),
);
},
// Callback function to build widget if exception occurs during fetching items
errorBuilder: (BuildContext context, LoadErrorDetails details, CustomListViewState state) {
return Column(
children: <Widget>[
Text(details.error.toString()),
RaisedButton(
onPressed: () => state.loadMore(),
child: Text('Retry'),
),
],
);
},
// Item count
itemCount: 45,
// A callback function called when pull to refresh is triggered
onRefresh: () async {
...
},
// Enable / disable pull to refresh (default: false)
disableRefresh: false,
),
Adapters
ListView Utils currently only supports network adapter. Or you could write your own adapter by implementing BaseListAdapter
mixin or using ListAdapter
class.
Here's simple network adapter code using jsonplaceholder data.
NetworkListAdapter(
url: 'https://jsonplaceholder.typicode.com/posts',
limitParam: '_limit',
offsetParam: '_start',
),
Controllers
Scroll controller
ListView Utils supports Flutter's built-in ScrollController
,
which allows for controlling the scrolling position:
class _SomeWidgetState extends State<SomeWidget> {
ScrollController scrollController = ScrollController();
@override
Widget build(BuildContext context) {
return Column(
children: [
FlatButton(
onPressed: () {
scrollController.animateTo(100);
},
child: const Text('Scroll down'),
),
Expanded(
child: CustomListView(
adapter: ...,
scrollController: scrollController,
itemBuilder: (context, index, dynamic item) {
return ListTile(
title: Text(item['title']),
);
},
),
),
],
);
}
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
}
List controller
ListView Utils also supports its own custom controller, which allows for controlling the list of items (for example, programmatically refreshing the list):
class _SomeWidgetState extends State<SomeWidget> {
CustomListViewController listViewController = CustomListViewController();
@override
Widget build(BuildContext context) {
return Column(
children: [
FlatButton(
onPressed: () {
listViewController.refresh();
},
child: const Text('Refresh'),
),
Expanded(
child: CustomListView(
adapter: ...,
loadingBuilder: (context) => const Center(
child: CircularProgressIndicator(),
),
scrollController: scrollController,
itemBuilder: (context, index, dynamic item) {
return ListTile(
title: Text(item['title']),
);
},
),
),
],
);
}
@override
void dispose() {
listViewController.dispose();
super.dispose();
}
}