paginated_live_list 0.2.0 copy "paginated_live_list: ^0.2.0" to clipboard
paginated_live_list: ^0.2.0 copied to clipboard

pagination of data and real-time updates with emphasis on resources effeciency

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:

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);
}

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';

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;
    }
  }
}

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;
  }
}

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);
  }
  • 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);
  }
  • 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));
  }

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);
        },
      ),
    );
  }

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.

2
likes
90
pub points
0%
popularity

Publisher

unverified uploader

pagination of data and real-time updates with emphasis on resources effeciency

Repository (GitHub)
View/report issues

Documentation

API reference

License

BSD-3-Clause (LICENSE)

Dependencies

collection, flutter

More

Packages that depend on paginated_live_list