diff --git a/CHANGELOG.md b/CHANGELOG.md index c182098..d0491ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +## [0.2.6] - 8/28/2020 + +* Added `initialOffset` property - [#7](https://github.com/TheMisir/flutter-listutils/pull/7) +* Added `paginationMode` property - [#8](https://github.com/TheMisir/flutter-listutils/pull/8) + ## [0.2.5] - 8/2/2020 * Fixed [#6](https://github.com/TheMisir/flutter-listutils/issues/6) diff --git a/example/lib/main.dart b/example/lib/main.dart index 4f11216..c095bc2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -15,6 +15,8 @@ class HomeScreen extends StatelessWidget { appBar: AppBar(title: Text('🔌 ListView_Utils')), body: SafeArea( child: CustomListView( + paginationMode: PaginationMode.page, + initialOffset: 1, loadingBuilder: CustomListLoading.defaultBuilder, header: Container( height: 50, diff --git a/example/pubspec.lock b/example/pubspec.lock index 752f96a..bc19760 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -80,7 +80,7 @@ packages: path: ".." relative: true source: path - version: "0.2.5" + version: "0.2.6" matcher: dependency: transitive description: diff --git a/lib/src/custom_list_view.dart b/lib/src/custom_list_view.dart index 6768a76..35e8ad6 100644 --- a/lib/src/custom_list_view.dart +++ b/lib/src/custom_list_view.dart @@ -7,10 +7,26 @@ import 'package:flutter/material.dart'; import 'adapters/list_adapter.dart'; import 'types.dart'; +enum PaginationMode { + /// Offset increases by item count + /// + /// Example: + /// items?_offset=0 + /// items?_offset=10 + offset, + + /// Offset increases by +1 + /// + /// Example: + /// items?_offset=1 + /// items?_offset=2 + page +} + class CustomListView extends StatefulWidget { const CustomListView({ Key key, - this.paginationMode = CustomListView.OFFSET_MODE, + this.paginationMode = PaginationMode.offset, this.pageSize = 30, this.initialOffset = 0, this.header, @@ -36,16 +52,13 @@ class CustomListView extends StatefulWidget { assert(adapter != null || itemCount != null), assert(debounceDuration != null), assert(distanceToLoadMore != null), - assert(paginationMode == CustomListView.OFFSET_MODE || - paginationMode == CustomListView.PAGE_MODE), + assert(paginationMode != null), + assert(initialOffset != null), this.itemExtend = separatorBuilder == null ? itemExtend : null, super(key: key); - static const OFFSET_MODE = 0; - static const PAGE_MODE = 1; - - /// pagination mode (offset / page) - final int paginationMode; + /// Pagination mode (offset / page) + final PaginationMode paginationMode; /// Item count to request on each time list is scrolled to the end final int pageSize; @@ -133,11 +146,10 @@ class _CLVState { } class CustomListViewState extends State { - final ValueNotifier<_CLVState> _stateNotifier = - ValueNotifier(_CLVState.loading); + final _stateNotifier = ValueNotifier<_CLVState>(_CLVState.loading); final List items = []; - int _pageNumber = 0; + int _offset = 0; bool _reachedToEnd = false; bool _loading = false; bool _fetching = false; @@ -146,14 +158,15 @@ class CustomListViewState extends State { bool get loading => _loading; bool get fetching => _fetching; bool get reachedToEnd => _reachedToEnd; - int get pageNumber => _pageNumber; + int get offset => _offset; @override void initState() { super.initState(); - _pageNumber = widget.initialOffset; - if (!loadMore()) { + _offset = widget.initialOffset; + + if (!loadMore(offset: widget.initialOffset)) { _stateNotifier.value = _CLVState.idle; } } @@ -165,19 +178,24 @@ class CustomListViewState extends State { } Future fetchFromAdapter({int offset, bool merge = true}) async { - if (_fetching) return; - _fetching = true; + if (_fetching) { + return; + } else { + _fetching = true; + } + + switch (widget.paginationMode) { + case PaginationMode.offset: + _offset = offset ?? items?.length ?? _offset; + break; + + case PaginationMode.page: + _offset = offset ?? (_offset + 1); + break; + } try { - int skip; - if (widget.paginationMode == CustomListView.OFFSET_MODE) - skip = offset ?? items?.length ?? 0; - else if (widget.paginationMode == CustomListView.PAGE_MODE) { - skip = offset ?? _pageNumber; - _pageNumber++; - } else - skip = 0; - ListItems result = await widget.adapter.getItems(skip, widget.pageSize); + var result = await widget.adapter.getItems(_offset, widget.pageSize); if (mounted) { setState(() { @@ -208,7 +226,7 @@ class CustomListViewState extends State { /// Returns true if loading was triggered, or false if loading is not /// triggered because of might be already loading or there is not a source for /// loading data from. - bool loadMore() { + bool loadMore({int offset}) { if (_reachedToEnd || _loading || widget.adapter == null) return false; if (_loadDebounce?.isActive ?? false) _loadDebounce.cancel(); @@ -217,7 +235,7 @@ class CustomListViewState extends State { _stateNotifier.value = _CLVState.loading; try { - await fetchFromAdapter(); + await fetchFromAdapter(offset: offset); _stateNotifier.value = _CLVState.idle; } catch (e) { _stateNotifier.value = _CLVState.createError(e); diff --git a/pubspec.yaml b/pubspec.yaml index c858927..4d9d377 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: listview_utils description: Infinite scrolling list view with multiple data source mode support using adapters. Also supports header, footer widgets. -version: 0.2.5 +version: 0.2.6 homepage: https://github.com/TheMisir/flutter-listutils environment: