DEV Community

Cover image for Flutter Web and Slivers
aseem wangoo
aseem wangoo

Posted on • Updated on

Flutter Web and Slivers

In case it helped :)
Pass Me A Coffee!!

Begin…

View the demo here

Website: https://fir-signin-4477d.firebaseapp.com/#/

Article here: https://flatteredwithflutter.com/flutter-web-and-slivers/

We will cover briefly about

  1. Slivers

What are Slivers?

As per the official doc:

A sliver is a portion of a scrollable area. You can use slivers to achieve custom scrolling effects.

You have possibly the entire control for implementing a scrollable area while using them. Because slivers can lazily build, they are particularly useful for scrolling through a large number of children.

One of the best articles on Slivers, here.

How to use Slivers in Flutter Web?

Just as you use, let's say, SingleChildScrollView for implementing a normal scrolling behavior, in terms of Slivers, you simply wrap your children inside a CustomScrollView

CustomScrollView(
  slivers: <Widget>[
    const SliverAppBar(
      pinned: true,
      expandedHeight: 250.0,
      flexibleSpace: FlexibleSpaceBar(
        title: Text('Demo'),
      ),
    ),
    SliverFixedExtentList(
      itemExtent: 50.0,
      delegate: SliverChildBuilderDelegate(
        (BuildContext context, int index) {
          return Container(
            alignment: Alignment.center,
            color: Colors.lightBlue[100 * (index % 9)],
            child: Text('List Item $index'),
          );
        },
      ),
    ),
  ],
)

Without slivers, you would have something like this

SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// WIDGETS
]
)
);

Sliver Widgets used for the demo

  1. SliverList

As per the docs:

A sliver that places multiple box children in a linear array along the main axis.

Flutter Web and Slivers
Flutter Web and Slivers

SliverList takes a delegate parameter. 

SliverList(
delegate: // 2 OPTIONS,
),
  • Option1 (SliverChildListDelegate): You can specify the predefined list of children with this.
SliverList(
delegate: SliverChildListDelegate(
[
Container(color: Colors.red, height: 150.0),
Container(color: Colors.purple, height: 150.0),
Container(color: Colors.green, height: 150.0),
],
),
);
  • Option2 (SliverChildBuilderDelegate): Specify the children with this, and they will be built lazily.
SliverList(
delegate: SliverChildBuilderDelegate((context, int index) {
return Container(color: Colors.blue, height: 150.0);
},
childCount: 10,
),
);

2. SliverPersistentHeader

As per the docs:

A sliver whose size varies when the sliver is scrolled to the edge of the viewport.

Flutter Web and Slivers
Flutter Web and Slivers

Here, the 2nd Widget (Disappear-header Sliver) is a SliverPersistentHeader.

As you scroll down, this widget sticks to the top of the page.

Flutter Web and Slivers
Flutter Web and Slivers

SliverPersistentHeader(
pinned: true,
floating: true,
delegate: _SliverDelegate(child: _menu),
),
  • pinned: Whether to stick the header to the start of the viewport once it has reached its minimum size.
  • floating: Whether the header should immediately grow again if the user reverses the scroll direction.
  • delegate parameter of the type SliverPersistentHeaderDelegate.
class _SliverDelegate implements SliverPersistentHeaderDelegate {
  _SliverDelegate({
    this.minHeight = 40.0,
    this.maxHeight = 56.0,
    @required this.child,
  });
final double minHeight;
  final double maxHeight;
  final Widget child;
@override
  Widget build(
    BuildContext context,
    double shrinkOffset,
    bool overlapsContent,
  ) {
    return SizedBox.expand(child: child);
  }
@override
  double get maxExtent => math.max(maxHeight, minHeight);
@override
  double get minExtent => minHeight;
@override
  bool shouldRebuild(_SliverDelegate oldDelegate) {
    return maxHeight != oldDelegate.maxHeight ||
        minHeight != oldDelegate.minHeight ||
        child != oldDelegate.child;
  }
@override
  FloatingHeaderSnapConfiguration get snapConfiguration => null;
@override
  OverScrollHeaderStretchConfiguration get stretchConfiguration => null;
}

3. SliverAppBar

As per the docs :

A material design app bar that integrates with a CustomScrollView.

Flutter Web and Slivers
Flutter Web and Slivers

As you scroll up, the app bar disappears, and you see the list of colors only. Something just like this:

SliverAppBar
SliverAppBar

Good interactive demos here

SliverAppBar(
  automaticallyImplyLeading: false,
  title: titleWidget,
  backgroundColor: AppColors.brandColor,
  expandedHeight: expandedHeight,
  flexibleSpace: FlexibleSpaceBar(
     background: Image.asset(image.assetName),
  ), 
),

Properties

  • automaticallyImplyLeading: To show the back arrow or not.
  • title: What widget to show (e.g here Text(‘SliverAppbar’))
  • expandedHeight: Size of the app bar when it is fully expanded.
  • flexibleSpace: Stacked behind the toolbar and the tab bar. The image in our case
  • floating: (By default, false) Whether the app bar should become visible as soon as the user scrolls towards the app bar.
  • pinned: (By default, false) Whether the app bar should remain visible at the start of the scroll view.

Note: For the demo, the default properties were good enough for me :)

4. SliverToBoxAdapter

As per the docs:

Creates a sliver that contains a single box widget.

SliverToBoxAdapter(
child: Container(
color: const Color(0xFF9b9987),
height: 300.0,
child: Center(
child: Text('SliverToBoxAdapter'),
),
),
)

Think of it as an alternative to a SizedBox, but for the sliver widgets.

SliverToBoxAdapter
SliverToBoxAdapter

5: SliverPadding

This is basically, “The amount of space by which to inset the child sliver.”

In the above screenshot, the white gap which you see between two widgets is the result of the SliverPadding.

SliverPadding(
    padding: const EdgeInsets.symmetric(vertical: 24.0),
    sliver: SliverFillRemaining(
      child: Container(
        color: const Color(0xFF442220),
        child: Center(
           child: Text(
             'SliverFillRemaining',
             style: TextStyle(color: Colors.white),
           ),
        ),
      ),
    ),
)

6: SliverFillRemaining

A sliver that contains a single box child that fills the remaining space. This should be the last sliver, as there is never any room for anything beyond this.

In the above example, the SliverFillRemaining covers the available space.

Production Tips :

  • In case you have a list of children, consider using SliverList, as they efficiently render the children.
  • For efficiently rendering a list inside Slivers, use SliverChildBuilderDelegate.
  • In order to have a customizable SliverAppBar, use SliverPersistentHeader, since SliverAppbar uses this under the hood.
  • For showing grids inside Slivers, consider using SliverGrid.
  • If each of the child height is fixed, you may switch to SliverFixedExtentList
SliverFixedExtentList(
  itemExtent: 50.0,
  delegate: SliverChildBuilderDelegate(
    (BuildContext context, int index) {
      return Container(
        alignment: Alignment.center,
        color: Colors.lightBlue[100 * (index % 9)],
        child: Text('list item $index'),
      );
    },
  ),
)

In case it helped :)
Pass Me A Coffee!!

Codepen: https://codepen.io/aseemwangoo/pens/

Hosted URL : https://fir-signin-4477d.firebaseapp.com/#/

Source code for Flutter Web App..

Top comments (0)