Flutter - CustomScrollView with Slivers Examples

In this tutorial, I'm going to explain what is CustomScrollView widget in Flutter and how to use it, along with some sliver widgets such as SliverAppBar, SliverToBoxAdapter and SliverList.

CustomScrollView

Flutter's CustomScrollView is basically a ScrollView with some effects. With CustomScrollView, you can create various scrolling effects like grids, lists, and expanding headers.

One of its properties is slivers, in which you can pass a collection of widgets. Each widget in slivers must have RenderSliver objects. Example of compatible widgets include SliverAppBar, SliverToBoxAdapter, SliverList, and SliverGrid.

Below is a basic example how to create a CustomScrollView widget.

  import 'package:flutter/material.dart';
  
  void main() => runApp(CustomScrollViewExample());
  
  class CustomScrollViewExample extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'CustomScrollView Tutorial by Woolha.com',
        home: Scaffold(
          body: CustomScrollView(
            slivers: <Widget>[
              // Place sliver widgets here
            ],
          ),
        ),
      );
    }
  }
  

SliverAppBar

The SliverAppBar is a material design app bar that's compatible with CustomScrollView. Basicaly it's an app bar with dynamic height and scroll effects. It's usually used as the first widget in the slivers list.

Here's a basic SliverAppBar example.

  slivers: <Widget>[
    SliverAppBar(
      title: Text("SliverAppBar Title"),
    )
  ],

With SliverAppBar, you can create an app bar whose height adapt automatically when the user scrolls the page.

SliverToBoxAdapter

SliverToBoxAdapter is a sliver containing a single box widget.

  slivers: <Widget>[
    SliverToBoxAdapter(
      child: SizedBox(
        height: 1000,
        child: Center(
          child: Text('Main content here'),
        ),
      ),
    ),
  ],

If you want to have multiple SliverToBoxAdapter widgets, it's better to consider using more suitable slivers such as SliverList, SliverFixedExtentList, SliverPrototypeExtentList or SliverGrid. The reason is those slivers only instantiate its visible children - which leads to better performance.

Flutter SliverToBoxAdapter

SliverList

SliverList is a sliver that holds multiple box children in a linear array along the main axis. Below is a simple SliverList that renders a collection of 50 Text widgets.

  slivers: <Widget>[
    SliverList(
      delegate: new SliverChildListDelegate(_buildList(50))
    ),
  ],

And here's the _buildList implementation:

  List _buildList(int count) {
    List<Widget> listItems = List();

    for (int i = 0; i < count; i++) {
      listItems.add(new Padding(padding: new EdgeInsets.all(20.0),
          child: new Text(
              'Item ${i.toString()}',
              style: new TextStyle(fontSize: 25.0)
          )
      ));
    }

    return listItems;
  }

Flutter SliverList

SliverGrid

If SliverList places its elements in one dimensional array, SliverGrid arranges its elements in two dimensional array.

  SliverGrid(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 5,
    ) ,
    delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
      return new Container(
        color: _randomColor(index),
        height: 200.0
      );
    }),
  ),

Below is the implementation of _randomColor:

  Color _randomColor(int index) {
    if (index % 3 == 0) {
      return Colors.pink;
    } else if (index % 3 == 1) {
      return Colors.blueAccent;
    }

    return Colors.amber;
  }

Flutter SliverGrid