Skip to content

Instantly share code, notes, and snippets.

@tranductam2802
Last active October 28, 2020 03:15
Show Gist options
  • Save tranductam2802/30c4b4dcdb2b6673e28327e17d2a3bee to your computer and use it in GitHub Desktop.
Save tranductam2802/30c4b4dcdb2b6673e28327e17d2a3bee to your computer and use it in GitHub Desktop.
Demo auto hide header of the scroll view
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
runApp(App());
}
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyWidget(),
);
}
}
class MyWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
final headerHeight = 200.0;
final controller1 = ScrollController(initialScrollOffset: headerHeight);
final controller2 = ScrollController(initialScrollOffset: headerHeight);
final controller3 = ScrollController(initialScrollOffset: headerHeight);
return Scaffold(
body: Column(
children: [
Container(
height: 700,
child: Row(
children: [
Expanded(
child: Container(
child: CustomScrollView(
controller: controller1,
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,
delegate: HideHeader(headerHeight: headerHeight),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: 50,
color:
index % 2 == 0 ? Colors.amber : Colors.black,
);
},
childCount: 12,
),
),
SliverFillRemainingHideHeader(
headerHeight: headerHeight,
),
],
),
),
),
Expanded(
child: Container(
child: CustomScrollView(
controller: controller2,
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,
delegate: HideHeader(headerHeight: headerHeight),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: 50,
color:
index % 2 == 0 ? Colors.amber : Colors.black,
);
},
childCount: 14,
),
),
SliverFillRemainingHideHeader(
headerHeight: headerHeight,
),
],
),
),
),
Expanded(
child: Container(
child: CustomScrollView(
controller: controller3,
slivers: <Widget>[
SliverPersistentHeader(
pinned: true,
delegate: HideHeader(headerHeight: headerHeight),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: 50,
color:
index % 2 == 0 ? Colors.amber : Colors.black,
);
},
childCount: 16,
),
),
SliverFillRemainingHideHeader(
headerHeight: headerHeight,
),
],
),
),
),
],
),
),
Expanded(
child: Container(
color: Colors.green,
),
),
],
),
);
}
}
class SliverFillRemainingHideHeader extends SingleChildRenderObjectWidget {
const SliverFillRemainingHideHeader({Key key, this.headerHeight = 0.0})
: super(key: key);
final double headerHeight;
@override
RenderSliverFillRemainingHideHeader createRenderObject(
BuildContext context) =>
RenderSliverFillRemainingHideHeader(headerHeight: headerHeight);
}
class RenderSliverFillRemainingHideHeader extends RenderSliverSingleBoxAdapter {
RenderSliverFillRemainingHideHeader(
{RenderBox child, this.headerHeight = 0.0})
: super(child: child);
final double headerHeight;
@override
void performLayout() {
final viewportExtent = constraints.viewportMainAxisExtent;
final scrollExtent = constraints.precedingScrollExtent;
double extent = viewportExtent - scrollExtent;
if (extent > -headerHeight) {
extent += headerHeight;
}
if (extent < 0.0) {
extent = 0.0;
}
assert(extent.isFinite);
final double paintedChildSize =
calculatePaintOffset(constraints, from: 0.0, to: extent);
assert(paintedChildSize.isFinite);
assert(paintedChildSize >= 0.0);
geometry = SliverGeometry(
scrollExtent: extent,
paintExtent: paintedChildSize,
maxPaintExtent: paintedChildSize,
hasVisualOverflow: extent > constraints.remainingPaintExtent ||
constraints.scrollOffset > 0.0,
);
}
}
class HideHeader extends SliverPersistentHeaderDelegate {
HideHeader({this.headerHeight});
final double headerHeight;
@override
Widget build(context, shrinkOffset, overlapsContent) =>
Container(color: Colors.blue);
@override
bool shouldRebuild(SliverPersistentHeaderDelegate _) => true;
@override
double get maxExtent => headerHeight;
@override
double get minExtent => 0.0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment