Rendering a combined list view from multiple list using Flutter’s SliverList
s
The previous post showed how to flatten grouped data with a header above the items so it can be rendered in a single ListView
widget. Now I want to look at a diffent use-case: Rendering lists from distinct data sources after each other. This implementation will use a CustomScrollView
and SliverList
s. If you’re unfamiliar with slivers, I would recommend reading Slivers, Demystified first, as the below example will just focus on this one narrow use-case, while the overall setup supports much more.
The Example
For this demo I want to render a single list showing the user’s favorite items, then some static content, and below that recommendations of similiar things. Since this simple example only has 3 row types, we could implement it using the ListView
approach shown before. But as the row types are never mixed together and since in this example there are only 3 sections (favorites list, static content, recommendations list) I think it’s a good case to create a widget for each section of the scroll view and then combine those into one scrollable list using CustomScrollView
.
On the top-level, the widget that sets up the list as a CustomScrollView
is nicely readable and gives a nice overview of what will be shown in it:
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
Favorites(),
Static(),
Recommendations(),
],
);
}
Now onto each sliver itself:
Favorites
renders aSliverList
with aSliverChildBuilderDelegate
; so it could handle a large amount of itemsStatic
uses aSliverChildListDelegate
in itsSliverList
as it renders just one very simple widgetRecommendations
uses the same approach aFavorites
, just with a different widget for its rows
So the Favorites
and Recommendation
builder methods look both roughly like this:
Widget build(BuildContext context) {
return SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return XyzRow(data: index); // might be `data[index]` in practice
},
childCount: 100, // might be `data.length` in practice
),
);
}
Overall the whole source code for this example looks to me a lot simpler than what we had in the previous case even though it seems like a more niche use case than rendering a grouped list. I think that stems from the fact that this “lists below each other” is nicely supported by the framework, while the grouped display was not.
In a real app one might need to combine the 2 approaches: Render a grouped list view from a flattened list with a SliverChildBuilderDelegate
inside a CustomScrollView
which also contains other lists. That is left as an exercise to the interested reader though 😉