I am using 2 Sliver Headers above GridView and a ListView on a CustomScrollView . I want only 1 of the headers (the one I am scrolling over) to be pinned When I scroll down. I want to be able to scroll down and only one of the headers is pinned when I pass over Gridview.
EDIT: Added _SliverAppBarDelegate
Scaffold(
body: SafeArea(
child: DefaultTabController(
length: 2,
child: CustomScrollView(
slivers: [
makeHeader('Categories', false),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.5,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
margin: EdgeInsets.all(5.0),
color: Colors.blue,
),
childCount: 10),
),
makeHeader('Watchlist', false),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.5,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Container(
margin: EdgeInsets.all(5.0),
color: Colors.red,
),
childCount: 10),
),
],
),
),
),
)
SliverPersistentHeader makeHeader(String headerText, bool pinned) {
return SliverPersistentHeader(
pinned: pinned,
floating: true,
delegate: _SliverAppBarDelegate(
minHeight: 40.0,
maxHeight: 60.0,
child: Container(
child: Text(
headerText,
style: TextStyle(fontSize: 24, color: Colors.green,fontWeight: FontWeight.bold),
)),
),
);
}
///////////////////////////EDIT
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.minHeight,
@required this.maxHeight,
this.child,
});
final double minHeight;
final double maxHeight;
final Widget child;
@override
double get minExtent => minHeight;
@override
double get maxExtent => math.max(maxHeight, minHeight);
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return new SizedBox.expand(child: child);
}
@override
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
return maxHeight != oldDelegate.maxHeight ||
minHeight != oldDelegate.minHeight ||
child != oldDelegate.child;
}
}