Making the Escapists Crafting Guide App 2 — SliverList and Sticky Headers

aldnav

Aldrin Navarro

Posted on December 25, 2020

Making the Escapists Crafting Guide App  2 — SliverList and Sticky Headers

On Part 1, I made the working version of the Escapists Crafting Guide app using Flutter. 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 — I describe it as a fancier list view. I am also exploring flutter_sticky_header[repository] [pub.dev] 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

Categories of tools source: Gamepedia The Escapists Crafting Guide

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 is a portion of a scrollable area. A sliver could be a SliverAppBar, SliverList, or a SliverGrid.

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.

[
  {
    "name": "Flimsy Pickaxe",
    "category": "Tools"
  },
  {
    "name": "Lightweight Pickaxe",
    "category": "Tools",
  },
  {
    "name": "Cup of Molten Chocolate",
    "category": "Weapon"
  }
]
Enter fullscreen mode Exit fullscreen mode

A function is required to create a map 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.

  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;
  }
Enter fullscreen mode Exit fullscreen mode

Sticky header

I am using flutter_sticky_header to achieve the sticky header effect. First, update pubspec.yaml.

dependencies:
  flutter_sticky_header: ^0.5.0
Enter fullscreen mode Exit fullscreen mode

Then run flutter pub get.

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

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
)
Enter fullscreen mode Exit fullscreen mode

The resulting code looks like the following.

Conclusion

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

  • A separator between categories on the list view

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

💖 💪 🙅 🚩
aldnav
Aldrin Navarro

Posted on December 25, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related