Discover how Slivers turn tricky scrolling screens into smooth, beautiful experiences with less code!
Why Slivers (SliverList, SliverGrid, SliverAppBar) in Flutter? - Purpose & Use Cases
Imagine you want to create a scrolling screen in your app with a list of items, a grid of pictures, and a header that changes size as you scroll. Doing this manually means writing lots of code to handle scrolling, resizing, and layout changes yourself.
Manually managing scrolling and different layouts is slow and tricky. You might end up with buggy scrolling, poor performance, or a UI that doesn't look smooth. It's like trying to juggle many balls at once without practice -- easy to drop them all.
Slivers in Flutter let you build complex scrolling effects easily. They handle scrolling, resizing, and layout changes for you. You just combine SliverList, SliverGrid, and SliverAppBar to create smooth, flexible scrollable screens without extra hassle.
SingleChildScrollView(
child: Column(
children: [
Header(),
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
),
GridView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
)
]
)
)CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('Sliver Demo'),
),
pinned: true,
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
);
},
childCount: 20,
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
childAspectRatio: 1.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: Colors.blue[100 * ((index % 8) + 1)],
child: Center(child: Text('Grid $index')),
);
},
childCount: 30,
),
),
]
)With Slivers, you can create beautiful, smooth scrolling screens that combine lists, grids, and flexible headers all in one place.
Think of a shopping app where the top banner shrinks as you scroll, the product list scrolls smoothly, and a grid of recommended items appears below--all working perfectly together thanks to Slivers.
Manual scrolling layouts are hard and error-prone.
Slivers simplify building complex scrollable UIs.
They improve performance and user experience.
Practice
SliverAppBar in a Flutter app?Solution
Step 1: Understand
SliverAppBarroleSliverAppBaris designed to create headers that can expand and collapse as the user scrolls.Step 2: Compare options with
Only To create a header that can expand, collapse, and stay visible when scrolling describes the expandable and pinned header behavior ofSliverAppBarbehaviorSliverAppBar.Final Answer:
To create a header that can expand, collapse, and stay visible when scrolling -> Option DQuick Check:
SliverAppBar= expandable header [OK]
- Confusing SliverAppBar with fixed AppBar
- Thinking SliverAppBar creates grids or lists
- Assuming SliverAppBar is a footer widget
SliverList inside a CustomScrollView?Solution
Step 1: Recall
SliverListconstructorSliverListrequires adelegateparameter, usuallySliverChildBuilderDelegateorSliverChildListDelegate.Step 2: Check each option's syntax
SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index')))correctly usesdelegate: SliverChildBuilderDelegate. Options A, B, and C use invalid parameters or properties.Final Answer:
SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index'))) -> Option BQuick Check:
SliverList needs delegate =SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index')))[OK]
- Using children instead of delegate
- Using itemBuilder directly on SliverList
- Passing items instead of delegate
CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: 100,
pinned: true,
flexibleSpace: FlexibleSpaceBar(title: Text('Hello')),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('Item $index')),
childCount: 3,
),
),
],
)Solution
Step 1: Analyze
The app bar is pinned and has a flexible space with title 'Hello', so it stays visible when scrolling.SliverAppBarpropertiesStep 2: Analyze
The list builds 3 items labeled 'Item 0', 'Item 1', and 'Item 2'.SliverListdelegateFinal Answer:
A scrollable view with a pinned app bar titled 'Hello' and 3 list items labeled Item 0 to Item 2 -> Option AQuick Check:
Pinned SliverAppBar + SliverList with 3 items = A scrollable view with a pinned app bar titled 'Hello' and 3 list items labeled Item 0 to Item 2 [OK]
- Thinking pinned means static, not scrollable
- Confusing list items count or labels
- Assuming SliverAppBar cannot be pinned
CustomScrollView(
slivers: [
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
children: List.generate(4, (index) => Container(color: Colors.blue)),
),
],
)Solution
Step 1: Check
SliverGridconstructor requirementsSliverGridrequires adelegateparameter, notchildren.Step 2: Validate other parts
SliverGridDelegateWithFixedCrossAxisCountis valid, andList.generatecan be used inside a delegate.Final Answer:
SliverGrid requires a delegate, not a children parameter -> Option CQuick Check:
SliverGrid needs delegate, not children [OK]
- Using children instead of delegate in SliverGrid
- Confusing SliverGridDelegateWithFixedCrossAxisCount as invalid
- Thinking CustomScrollView disallows SliverGrid
Solution
Step 1: Identify correct widget for scrollable slivers
CustomScrollViewwithsliversparameter is needed to combineSliverAppBar,SliverGrid, andSliverList.Step 2: Check each option's structure
CustomScrollView(slivers: [SliverAppBar(pinned: true, expandedHeight: 200, flexibleSpace: FlexibleSpaceBar(title: Text('Gallery'))), SliverGrid(delegate: SliverChildBuilderDelegate((c, i) => Image.network(urls[i]), childCount: urls.length), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3)), SliverList(delegate: SliverChildBuilderDelegate((c, i) => ListTile(title: Text(items[i])), childCount: items.length))])correctly usesCustomScrollViewwith slivers and proper delegates.ListView(children: [AppBar(title: Text('Gallery')), GridView.count(crossAxisCount: 3, children: images), ListView(children: texts)])uses nested scrollables incorrectly.CustomScrollView(children: [SliverAppBar(), SliverGrid(), SliverList()])useschildreninstead ofslivers.Column(children: [SliverAppBar(), SliverGrid(), SliverList()])usesColumnwhich cannot host slivers.Final Answer:
CustomScrollView with SliverAppBar, SliverGrid, and SliverList using delegates -> Option AQuick Check:
Use CustomScrollView with slivers and delegates =CustomScrollView(slivers: [SliverAppBar(pinned: true, expandedHeight: 200, flexibleSpace: FlexibleSpaceBar(title: Text('Gallery'))), SliverGrid(delegate: SliverChildBuilderDelegate((c, i) => Image.network(urls[i]), childCount: urls.length), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3)), SliverList(delegate: SliverChildBuilderDelegate((c, i) => ListTile(title: Text(items[i])), childCount: items.length))])[OK]
- Using ListView or Column instead of CustomScrollView for slivers
- Passing slivers as children instead of slivers parameter
- Not using delegates for SliverGrid and SliverList
Ready to prove it?
Pass the test and this pattern moves unknown
