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
- 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
- SliverList
As per the docs:
A sliver that places multiple box children in a linear array along the main axis.
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.
Here, the 2nd Widget (Disappear-header Sliver) is a SliverPersistentHeader.
As you scroll down, this widget sticks to the top of the page.
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.
As you scroll up, the app bar disappears, and you see the list of colors only. Something just like this:
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.
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'),
);
},
),
)
Codepen: https://codepen.io/aseemwangoo/pens/
Hosted URL : https://fir-signin-4477d.firebaseapp.com/#/
Top comments (0)