CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件。如果需要创建可展开的AppBar,后跟list和Grid,可使用这三种Slivers:SliverAppBar,SliverList和SliverGrid。
class CustomScrollViewDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _CustomScrollViewDemoState();
}
}
class _CustomScrollViewDemoState extends State<CustomScrollViewDemo> {
ScrollController scrollController = new ScrollController();
bool showToTopBtn = false;
double screenHeight;
@override
void initState() {
super.initState();
scrollController.addListener(() {
print(scrollController.positions.length);
print(scrollController.position.toString());
if (scrollController.offset < screenHeight && showToTopBtn) {
setState(() {
showToTopBtn = false;
});
} else if (scrollController.offset >= screenHeight && showToTopBtn == false) {
setState(() {
showToTopBtn = true;
});
}
});
}
@override
void dispose() {
scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
screenHeight = MediaQuery.of(context).size.height;
print("screenHeight = " + screenHeight.toString());
return Scaffold(
floatingActionButton: !showToTopBtn
? null
: FloatingActionButton(
child: Icon(Icons.arrow_upward),
onPressed: () {
scrollController.animateTo(0,
duration: Duration(milliseconds: 200), curve: Curves.ease);
},
),
body: CustomScrollView(
controller: scrollController,
slivers: <Widget>[
SliverAppBar(
leading: Icon(Icons.arrow_back),
centerTitle: true,
title: const Text('Demo'),
pinned: true,
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset(
"images/food01.jpeg",
fit: BoxFit.cover,
),
),
),
SliverPadding(
padding: EdgeInsets.all(8),
sliver: SliverGrid(
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 4),
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.cyan[100 * (index % 9)],
child: new Text('grid item $index'),
);
}, childCount: 20),
),
),
SliverFixedExtentList(
itemExtent: 50,
delegate:
SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: new Text('list item $index'),
);
}, childCount: 50),
)
],
),
);
}
}
上述代码实现了CustomScrollView中嵌套SliverAppBar,SliverPadding,SliverGrid,SliverFixedExtendedList,,并且加入了滑动控制(大于一屏时显示回顶部按钮)
class _CustomScrollViewDemoState extends State<CustomScrollViewDemo> {
...;
String _progress = "0%";
...
@override
Widget build(BuildContext context) {
screenHeight = MediaQuery.of(context).size.height;
print("screenHeight = " + screenHeight.toString());
return Scaffold(
...
body: Scrollbar(
child: NotificationListener<ScrollNotification>(
onNotification: (ScrollNotification notification) {
double progress = notification.metrics.pixels /
notification.metrics.maxScrollExtent;
//重新构建
setState(() {
_progress = "${(progress * 100).toInt()}%";
});
print("BottomEdge: ${notification.metrics.extentAfter == 0}");
},
child: Stack(
alignment: Alignment.center,
children: <Widget>[
CustomScrollView(
....
),
CircleAvatar(
radius: 30.0,
child: Text(_progress),
backgroundColor: Colors.black54,
)
],
),
),
),
);
}
}
与之前不同的地方已经标识出来了,结果为