Making the Escapists Crafting Guide App  2 — SliverList and Sticky Headers
Tags: flutter, dart, mobile
Published: 2020-12-25 12:12:07

On [Part 1](/blog/making-the-escapists-crafting-guide-app), I made the working version of the Escapists Crafting Guide app using [Flutter](https://flutter.dev/). I used `ListView` widget to show the different tools and items available for crafting.

Today I am going to improve the app slightly by showing on the list the category where these tools belong. I am also going to replace the `ListView` with [`SliverList`](https://api.flutter.dev/flutter/widgets/SliverList-class.html) — I describe it as a fancier list view. I am also exploring `flutter_sticky_header`[[repository]](https://github.com/letsar/flutter_sticky_header) [[pub.dev]](https://pub.dev/packages/flutter_sticky_header) to achieve the behavior when the user scrolls and the category sticks to the top until the next category is in the current view. I will also be polishing the design along the way.


![alt Categories of tools](https://dev-to-uploads.s3.amazonaws.com/i/vg9qexss6wxs0xk99wm2.png)

_Categories of tools [source: Gamepedia The Escapists Crafting Guide](https://theescapists.gamepedia.com/Crafting)_

## SliverList

To use the SliverList, it needs to be wrapped on a `CustomScrollView` which comes with the familiar API that we already learned from using `ListView` with slight changes. This widget requires a list of children widgets called `slivers`.

_[A sliver](https://flutter.dev/docs/development/ui/advanced/slivers) is a portion of a scrollable area._ A sliver could be a [SliverAppBar](https://youtu.be/R9C5KMJKluE), [SliverList](https://api.flutter.dev/flutter/widgets/SliverList-class.html), or a [SliverGrid](https://api.flutter.dev/flutter/widgets/SliverGrid-class.html).

{% gist https://gist.github.com/aldnav/d1ff2d12953351c88ca8dde0b09a3f88 file=custom_scroll_view_example.dart %}

### Data structure

Previously, I was just working with a linear list of all items. Right now I need to refactor it to group the tools by categories.

My input data contains a list of items, and for each item it has a category.

```json
[
  {
    "name": "Flimsy Pickaxe",
    "category": "Tools"
  },
  {
    "name": "Lightweight Pickaxe",
    "category": "Tools",
  },
  {
    "name": "Cup of Molten Chocolate",
    "category": "Weapon"
  }
]
```

A function is required to create a [`map`](https://dart.dev/guides/language/language-tour#maps) data structure of the tools. The map will then be used to build the slivers. The slivers will contain the category as the header — the one that sticks to the top when scrolled, and then followed by the rest of the items belonging to the category.

```dart
  Map categorizeItems(items) {
    var categories = Map();
    items.forEach((element) {
      if (!categories.containsKey(element.category)) {
        categories[element.category] = List();
      }
      categories[element.category].add(element);
    });
    return categories;
  }
```

### Sticky header

I am using [`flutter_sticky_header`](https://github.com/letsar/flutter_sticky_header) to achieve the sticky header effect. First, update  `pubspec.yaml`.

```yaml
dependencies:
  flutter_sticky_header: ^0.5.0
```

Then run `flutter pub get`.

The basic structure looks like below. Each one of this is a child of the `CustomScrollView.slivers`

```dart
SliverStickyHeader(
    header: Header(title: category),
    sliver: SliverList(
        delegate: SliverChildBuilderDelegate(
            (BuildContext context, int index) {
                return InkWell(
                    child: ItemCard(data: items[index]),
                    onTap: () {...}
                );
            },
            childCount: items.length,
        ), // SliverChildBuilderDelegate
    ), // SliverList
)
```

The resulting code looks like the following.

{% gist https://gist.github.com/aldnav/d1ff2d12953351c88ca8dde0b09a3f88 file=sliverlist.dart %}


## Conclusion

Now, I have finally ticked off an improvement. Will continue to do more.

> - A separator between categories on the list view

{% vimeo 494628992 %}

Next, I will be using another sliver to achieve a feature that I always wanted to have — a complete spread or a tree, not just the immediate requirements, to show all components required to craft a tool.

Until next time!

#### References

- SliverList class https://api.flutter.dev/flutter/widgets/SliverList-class.html
- Using slivers to achieve fancy scrolling https://flutter.dev/docs/development/ui/advanced/slivers
- Dart Maps https://dart.dev/guides/language/language-tour#maps