Slivers in Flutter - Part (2)
SliverPersistentHeader, SliverFixedExtentList, SliverPrototypeExtentList, SliverFillViewport, SliverToBoxAdapter, SliverFillRemaining, SliverPadding

Search for a command to run...
SliverPersistentHeader, SliverFixedExtentList, SliverPrototypeExtentList, SliverFillViewport, SliverToBoxAdapter, SliverFillRemaining, SliverPadding

No comments yet. Be the first to comment.
Lessons from Code, Content, and Consistency

Reliability basics: Outbox pattern + why it matters

Introducing Kafka/Redpanda + move to event-driven workflow

Connect Orders ↔ Inventory (first working service-to-service flow)

Inventory service + gRPC + proto contracts

sliver whose size varies when it is scrolled.pinned - Stick the Header at the top.floating - Header will immediately grow again if the user scrolls down.delegate - It takes a class which extends SliverPersistentHeaderDelegate. We have to override build method which has 3 arguments -
context,shrinkOffset,overlapsContent.
context is the BuildContext of the sliver.overlapsContent argument is true if subsequent slivers (if any) will
be rendered beneath this one, and false if the sliver will not have any contents below it.shrinkOffset is a distance from maxExtent towards minExtent representing the current amount by which the sliver has been shrunk. It is useful when you want to update any widget property with respect to the scrollOffeset. For example, When
user starts scrolling the Text defined in the Header fades away.
CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: MySliverHeader(maxExtent: 250.0, minExtent: 100.0),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
height: 50,
alignment: Alignment.center,
color: index.isEven ? Colors.grey : Colors.amberAccent,
child: Text('List item : $index'),
);
},
childCount: 50,
),
),
],
),
class MySliverHeader extends SliverPersistentHeaderDelegate {
MySliverHeader({
required this.minExtent,
required this.maxExtent,
});
final double minExtent;
final double maxExtent;
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
print(shrinkOffset);
return Stack(
fit: StackFit.expand,
children: [
Image.network(
"url",
fit: BoxFit.cover,
),
Positioned(
left: 16,
top: 26,
right: 16,
bottom: 16,
child: Opacity(
opacity: 1.0 - max(0.0, shrinkOffset) / maxExtent,
child: Text(
"Mountains",
style: Theme.of(context).textTheme.headline3!.copyWith(
color: Colors.black,
),
),
),
)
],
);
}
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return true;
}
}
itemExtent. The unit used here is px. SliverFixedExtentList(
delegate: SliverChildListDelegate([
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.green,
),
]),
itemExtent: 50,
),

SliverPrototypeExtentList(
delegate: SliverChildListDelegate([
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.green,
),
]),
prototypeItem: SizedBox(
height: 150,
),
),
// all the Container will get 150px of height as defined in the prototype

CustomScrollView(
slivers: [
SliverFillViewport(
delegate: SliverChildListDelegate([
Container(
color: Colors.red,
),
Container(
color: Colors.blue,
),
Container(
color: Colors.green,
),
]),
),
],
),

CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: MySliverHeader(maxExtent: 250.0, minExtent: 100.0),
),
SliverToBoxAdapter(
child: Text(
"long long text.....",
style: TextStyle(fontSize: 18),
)),
],
),


FooterCustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
child: Container(
color: Colors.grey,
height: 550.0,
child: Center(
child: Text(
"Content",
style: TextStyle(fontSize: 28),
),
),
),
),
SliverFillRemaining(
hasScrollBody: false,
child: Container(
color: Colors.blue[100],
child: Center(
child: Text(
"Footer",
style: TextStyle(fontSize: 28),
),
)),
),
],
);

hasScrollBody flag indicates whether the sliver's child has a scrollable body. This value is never null, and defaults to true.fillOverScroll is used when we want to fill the empty space when the user scrolls towards the AppBar. SliverFillRemaining(
fillOverscroll: true,
hasScrollBody: false,
child: Container(
color: Colors.blueGrey,
child: Center(
child: Text(
"Footer",
style: TextStyle(fontSize: 22),
),
),
),
)

Padding widget works. The only difference is it takes sliver instead of child.sliver widget by wrapping it inside the SliverPadding widget. SliverPadding(
padding: EdgeInsets.all(12),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
height: 50,
alignment: Alignment.center,
color: index.isEven ? Colors.grey : Colors.amberAccent,
child: Text('List item : $index'),
);
},
childCount: 10,
),
),
),

Previous Article:
