Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/superlistapp/super_sliver_list

Drop-in replacement for SliverList and ListView that can handle large amount of items with variable extents and reliably jump / animate to any item.
https://github.com/superlistapp/super_sliver_list

Last synced: about 2 months ago
JSON representation

Drop-in replacement for SliverList and ListView that can handle large amount of items with variable extents and reliably jump / animate to any item.

Lists

README

        

# SliverList and ListView - Supercharged

> See the [live example](https://superlistapp.github.io/super_sliver_list/#/) of `SuperSliverList`.

`SuperSliverList` and `SuperListView` are drop in replacement widgets for `SliverList` and `ListView` with greatly improved performance and additional features:

#### Fast scrolling with large amount of items with variable extents

`SliverList` performance degrades heavily when quickly scrolling through a large amount of items with different extents, requiring workarounds such as using `FixedExtentSliverList` or prototype items. `SuperSliverList` uses different layout algorithm and can handle virtually unlimited number of items with variable extents without any slow-downs.

#### Ability to jump or animate to specific item

`SliverList` does not provide any way to jump or animate a particular index. There is a [scrollable_positioned_list](https://pub.dev/packages/scrollable_positioned_list) package that provides this functionality, but it comes at a cost, as it requires custom scroll view, does not seem to work properly with Scrollbars, can't be used with with other slivers (such as sticky headers) and ultimately is backed by a `SliverList` so it has the same performance issues as mentioned above.

`SuperSliverList` provides a way to reliably jump and animate to a specific item, even if the item is outside of the viewport and has not been built or laid out yet.

#### Smooth and predictable scrollbar behavior

`SliverList` is quite prone to scrollbar erraticaly jumping around when scrolling through a list of items with different extents. With `SuperSliverList` the scrollbar should behave more predictably. See the [Advanced](#advanced) section for more details.

## Basic Usage

`SuperListView` is a drop-in replacement for `ListView`, and as such you can use it same way you'd use `ListView`:

```dart
SuperListView.builder(
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
)
```

`SuperSliverList` is a drop-in replacement for `SliverList` and should work with any `CustomScrollView` configuration:
```dart
CustomScrollView(
slivers: [
SliverPadding(
padding: const EdgeInsets.all(20.0),
sliver: SuperSliverList(
delegate: SliverChildListDelegate(
[
const Text("I'm dedicating every day to you"),
const Text('Domestic life was never quite my style'),
const Text('When you smile, you knock me out, I fall apart'),
const Text('And I thought I was so smart'),
],
),
),
),
],
)
```

## Jumping and animating to specific item

`ListController` can be provided to `SuperSliverList`/`SuperListView` and used to jump or animate to specific item:

```dart
class _MyState extends State {
final _listController = ListController();
final _scrollController = ScrollController();

@override
Widget build(BuildContext context) {
return SuperListView.builder(
listController: _listController,
controller: _scrollController,
itemCount: 1000,
itemBuilder: (context, index) {
return ListTile(title: Text('Item $index'));
},
);
}

void jumpToItem(int index) {
_listController.jumpToItem(
index: index,
scrollController: _scrollController,
alignment: 0.5,
);
}

void animateToItem(int index) {
_listController.animateToItem(
index: index,
scrollController: _scrollController,
alignment: 0.5,
// You can provide duration and curve depending on the estimated
// distance between currentPosition and the target item position.
duration: (estimatedDistance) => Duration(milliseconds: 250),
curve: (estimatedDistance) => Curves.easeInOut,
);
}
}
```

## Advanced

Very roughtly speaking `SuperSliverList` works by estimating the extent of items that are outside of viewport and when these items are scrolled into the viewport cache area the scroll position is transparently adjusted to account of the difference between estimated and actual extents. On small lists this difference may result in scrollbar movement not being perfectly aligned with list movement. `SuperSliverList` provides two ways to rectify this:

### Improve extent estimation

You can register custom callback that will be used to estimate extent of estimated items. This can be useful if you have an idea, atleast approximately, how large the extent of each item is.

```dart
SuperSliverList(
delegate: /*...*/,
estimateExtent: (index) => 100.0, // Provide your own extent estimation
)
```

### Precalculate extents for items

`SuperSliverList` can, if needed, asynchronously precalculate extents for items. To enfore this, subclass `ExtentPrecalculationPolicy` and provide it to `SuperSliverList`:

In this example the extents are eagerly precalculated for lists with less than 100 items:

```dart
class MyPrecalculationPolicy extends ExtentPrecalculationPolicy {
@override
bool shouldPrecaculateExtents(ExtentPrecalculationContext context) {
return context.numberOfItems < 100;
}
}

return SuperSliverList(
delegate: /*...*/,
extentPrecalculationPolicy: myPolicy,
)
```

The threshold is arbitrary, but in general there are diminishing returns for precalculating extents for large lists, as the extent estimation error for each item has much smaller impact on the scrollbar position if there are many items.

## Example

See the [example](example) folder for a complete sample app using `SuperSliverList`. You can also see the [example deployed live](https://superlistapp.github.io/super_sliver_list/).