Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rovkinmax/4fd833dc93a937ac3136ccc14b39797f to your computer and use it in GitHub Desktop.
Save rovkinmax/4fd833dc93a937ac3136ccc14b39797f to your computer and use it in GitHub Desktop.
/// Помощник с логикой пагинации
class PaginationHelper<T> {
static const double _defaultPaginationOffset = 50;
/// Смещение от конца прокрутки после которого начинать пагинацию
double paginationOffset;
/// Контроллер прокрутки
ScrollController scrollController;
final EntityStreamedState<List<T>> dataState;
final StreamedState<PaginationData> paginationState = StreamedState()
..accept(PaginationData<T>());
/// Колбэк для подгрузки данных
VoidCallback loadMore;
/// Данные пагинации
PaginationData get paginationData => paginationState.value;
/// Если загружено максимальное количество данных
bool get _isAllDataLoaded => paginationData.isLimited ?? false;
bool get _isLoadingForbidden => dataState.value.isLoading || _isAllDataLoaded;
StreamSubscription _paginationSubscription;
PaginationHelper({
double paginationOffset,
@required this.scrollController,
@required this.loadMore,
@required this.dataState,
}) : paginationOffset = paginationOffset ?? _defaultPaginationOffset {
_init();
}
void dispose() {
scrollController.removeListener(_handleScroll);
_paginationSubscription?.cancel();
}
/// Обнулить данные
void reset() {
paginationData.offset = 0;
paginationData.data = null;
paginationState.accept(paginationData);
}
/// Обновить данные
void update(List<T> data, [int limit]) {
if (limit != null) paginationData?.limit = limit;
paginationState.accept(paginationData..concat(data));
}
/// Получить слудующее смещение данных
int next() => paginationData.next();
void _init() {
scrollController.addListener(_handleScroll);
_paginationSubscription = paginationState.stream.listen(_subscribe);
}
void _subscribe(PaginationData paginationData) {
dataState.content(paginationData.data);
}
void _handleScroll() {
if (scrollController.offset >
scrollController.position.maxScrollExtent - paginationOffset) {
if (_isLoadingForbidden) return;
loadMore();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment