Bird
Raised Fist0
Fluttermobile~7 mins

Slivers (SliverList, SliverGrid, SliverAppBar) in Flutter

Choose your learning style10 modes available
Introduction

Slivers help you create smooth scrolling effects with flexible layouts in Flutter. They let you build lists, grids, and app bars that can change size or behavior as you scroll.

When you want a list that scrolls with a header that shrinks or expands.
When you want to show items in a grid that scrolls smoothly.
When you want a custom app bar that changes size or sticks at the top while scrolling.
When you want to combine different scrolling effects in one screen.
When you want better performance for large scrollable areas by loading items lazily.
Syntax
Flutter
class MySliverWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CustomScrollView(
      slivers: [
        SliverAppBar(
          title: Text('Title'),
          expandedHeight: 200,
          flexibleSpace: FlexibleSpaceBar(
            background: Image.asset('path/to/image.jpg', fit: BoxFit.cover),
          ),
          pinned: true,
        ),
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) => ListTile(title: Text('Item $index')),
            childCount: 10,
          ),
        ),
        SliverGrid(
          delegate: SliverChildBuilderDelegate(
            (context, index) => Container(color: Colors.blue, child: Center(child: Text('Grid $index'))),
            childCount: 6,
          ),
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        ),
      ],
    );
  }
}

SliverAppBar creates a flexible app bar that can expand and collapse.

SliverList builds a scrollable list of widgets lazily.

SliverGrid builds a scrollable grid of widgets lazily.

Examples
This creates an app bar that stays visible (pinned) and expands with an image background.
Flutter
SliverAppBar(
  title: Text('My AppBar'),
  pinned: true,
  expandedHeight: 150,
  flexibleSpace: FlexibleSpaceBar(
    background: Image.network('https://example.com/image.jpg', fit: BoxFit.cover),
  ),
)
This shows an empty list because childCount is zero (edge case: empty list).
Flutter
SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) => ListTile(title: Text('Item $index')),
    childCount: 0,
  ),
)
This shows a grid with only one item (edge case: single element grid).
Flutter
SliverGrid(
  delegate: SliverChildBuilderDelegate(
    (context, index) => Container(color: Colors.red, child: Text('Grid $index')),
    childCount: 1,
  ),
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 1),
)
This shows a list with only one item at the start (edge case: single element list).
Flutter
SliverList(
  delegate: SliverChildBuilderDelegate(
    (context, index) => ListTile(title: Text('First Item')), 
    childCount: 1,
  ),
)
Sample App

This app shows a scrollable screen with a flexible app bar at the top. The app bar has a Flutter logo that expands and shrinks as you scroll. Below it is a list of 5 items, followed by a grid of 4 colored items arranged in 2 columns.

Flutter
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: CustomScrollView(
          slivers: [
            SliverAppBar(
              title: const Text('Sliver Demo'),
              expandedHeight: 150,
              flexibleSpace: const FlexibleSpaceBar(
                background: FlutterLogo(size: 200),
              ),
              pinned: true,
            ),
            SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(title: Text('List Item $index')),
                childCount: 5,
              ),
            ),
            SliverGrid(
              delegate: SliverChildBuilderDelegate(
                (context, index) => Container(
                  color: index.isEven ? Colors.blue : Colors.green,
                  child: Center(child: Text('Grid Item $index', style: const TextStyle(color: Colors.white))),
                ),
                childCount: 4,
              ),
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
            ),
          ],
        ),
      ),
    );
  }
}
OutputSuccess
Important Notes

Time complexity: Slivers load items lazily, so scrolling is efficient even with many items.

Space complexity: Only visible items are kept in memory, saving space.

Common mistake: Forgetting to use CustomScrollView to hold slivers causes errors.

Use SliverList for vertical lists and SliverGrid for grids inside scroll views.

SliverAppBar is great for flexible headers that react to scrolling.

Summary

Slivers let you build scrollable areas with flexible headers, lists, and grids.

Use SliverAppBar for a header that expands and pins on scroll.

Use SliverList and SliverGrid to build lazy-loading lists and grids inside CustomScrollView.

Practice

(1/5)
1. What is the main purpose of using SliverAppBar in a Flutter app?
easy
A. To replace the default app bar with a static title
B. To display a fixed footer at the bottom of the screen
C. To create a grid layout inside a scrollable area
D. To create a header that can expand, collapse, and stay visible when scrolling

Solution

  1. Step 1: Understand SliverAppBar role

    SliverAppBar is designed to create headers that can expand and collapse as the user scrolls.
  2. Step 2: Compare options with SliverAppBar behavior

    Only To create a header that can expand, collapse, and stay visible when scrolling describes the expandable and pinned header behavior of SliverAppBar.
  3. Final Answer:

    To create a header that can expand, collapse, and stay visible when scrolling -> Option D
  4. Quick Check:

    SliverAppBar = expandable header [OK]
Hint: Remember: SliverAppBar controls flexible headers [OK]
Common Mistakes:
  • Confusing SliverAppBar with fixed AppBar
  • Thinking SliverAppBar creates grids or lists
  • Assuming SliverAppBar is a footer widget
2. Which of the following is the correct way to create a SliverList inside a CustomScrollView?
easy
A. SliverList(items: List.generate(5, (index) => Text('Item $index')))
B. SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index')))
C. SliverList(itemBuilder: (context, index) => Text('Item $index'))
D. SliverList(children: [Text('Item 1'), Text('Item 2')])

Solution

  1. Step 1: Recall SliverList constructor

    SliverList requires a delegate parameter, usually SliverChildBuilderDelegate or SliverChildListDelegate.
  2. Step 2: Check each option's syntax

    SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index'))) correctly uses delegate: SliverChildBuilderDelegate. Options A, B, and C use invalid parameters or properties.
  3. Final Answer:

    SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index'))) -> Option B
  4. Quick Check:

    SliverList needs delegate = SliverList(delegate: SliverChildBuilderDelegate((context, index) => Text('Item $index'))) [OK]
Hint: SliverList always needs a delegate parameter [OK]
Common Mistakes:
  • Using children instead of delegate
  • Using itemBuilder directly on SliverList
  • Passing items instead of delegate
3. Given the code snippet below, what will be displayed on the screen?
CustomScrollView(
  slivers: [
    SliverAppBar(
      expandedHeight: 100,
      pinned: true,
      flexibleSpace: FlexibleSpaceBar(title: Text('Hello')),
    ),
    SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) => ListTile(title: Text('Item $index')),
        childCount: 3,
      ),
    ),
  ],
)
medium
A. A scrollable view with a pinned app bar titled 'Hello' and 3 list items labeled Item 0 to Item 2
B. A static app bar with title 'Hello' and 3 buttons labeled Item 1 to Item 3
C. An error because SliverAppBar cannot be pinned
D. A scrollable grid with 3 items and no app bar

Solution

  1. Step 1: Analyze SliverAppBar properties

    The app bar is pinned and has a flexible space with title 'Hello', so it stays visible when scrolling.
  2. Step 2: Analyze SliverList delegate

    The list builds 3 items labeled 'Item 0', 'Item 1', and 'Item 2'.
  3. Final Answer:

    A scrollable view with a pinned app bar titled 'Hello' and 3 list items labeled Item 0 to Item 2 -> Option A
  4. Quick 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]
Hint: Pinned SliverAppBar stays visible; SliverList shows items lazily [OK]
Common Mistakes:
  • Thinking pinned means static, not scrollable
  • Confusing list items count or labels
  • Assuming SliverAppBar cannot be pinned
4. Identify the error in the following Flutter code snippet using slivers:
CustomScrollView(
  slivers: [
    SliverGrid(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
      children: List.generate(4, (index) => Container(color: Colors.blue)),
    ),
  ],
)
medium
A. List.generate cannot be used inside SliverGrid
B. SliverGridDelegateWithFixedCrossAxisCount is not a valid class
C. SliverGrid requires a delegate, not a children parameter
D. CustomScrollView cannot contain SliverGrid

Solution

  1. Step 1: Check SliverGrid constructor requirements

    SliverGrid requires a delegate parameter, not children.
  2. Step 2: Validate other parts

    SliverGridDelegateWithFixedCrossAxisCount is valid, and List.generate can be used inside a delegate.
  3. Final Answer:

    SliverGrid requires a delegate, not a children parameter -> Option C
  4. Quick Check:

    SliverGrid needs delegate, not children [OK]
Hint: SliverGrid uses delegate, not children, for lazy loading [OK]
Common Mistakes:
  • Using children instead of delegate in SliverGrid
  • Confusing SliverGridDelegateWithFixedCrossAxisCount as invalid
  • Thinking CustomScrollView disallows SliverGrid
5. You want to create a scrollable screen with a header that expands and pins, followed by a grid of images with 3 columns, and then a list of text items. Which of the following is the best way to structure your Flutter widget tree?
hard
A. 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))])
B. ListView(children: [AppBar(title: Text('Gallery')), GridView.count(crossAxisCount: 3, children: images), ListView(children: texts)])
C. CustomScrollView(children: [SliverAppBar(), SliverGrid(), SliverList()])
D. Column(children: [SliverAppBar(), SliverGrid(), SliverList()])

Solution

  1. Step 1: Identify correct widget for scrollable slivers

    CustomScrollView with slivers parameter is needed to combine SliverAppBar, SliverGrid, and SliverList.
  2. 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 uses CustomScrollView with 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()]) uses children instead of slivers. Column(children: [SliverAppBar(), SliverGrid(), SliverList()]) uses Column which cannot host slivers.
  3. Final Answer:

    CustomScrollView with SliverAppBar, SliverGrid, and SliverList using delegates -> Option A
  4. Quick 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]
Hint: Use CustomScrollView with slivers and delegates for mixed scroll content [OK]
Common Mistakes:
  • Using ListView or Column instead of CustomScrollView for slivers
  • Passing slivers as children instead of slivers parameter
  • Not using delegates for SliverGrid and SliverList
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard