我们考虑一个这样的布局:一个滑动的视图中包括一个标题视图(HeaderView),一个列表视图(ListView),一个网格视图(GridView)。
我们怎么可以让它们做到统一的滑动效果呢?使用前面的滚动是很难做到的。
Flutter中有一个可以完成这样滚动效果的Widget:CustomScrollView,可以统一管理多个滚动视图。
在CustomScrollView中,每一个独立的,可滚动的Widget被称之为Sliver。
补充:Sliver可以翻译成裂片、薄片,你可以将每一个独立的滚动视图当做一个小裂片。
1. Slivers的基本使用
因为我们需要把很多的Sliver放在一个CustomScrollView中,所以CustomScrollView有一个slivers属性,里面让我们放对应的一些Sliver:
- SliverList:类似于我们之前使用过的ListView;
- SliverFixedExtentList:类似于SliverList只是可以设置滚动的高度;
- SliverGrid:类似于我们之前使用过的GridView;
- SliverPadding:设置Sliver的内边距,因为可能要单独给Sliver设置内边距;
- SliverAppBar:添加一个AppBar,通常用来作为CustomScrollView的HeaderView;
- SliverSafeArea:设置内容显示在安全区域(比如不让齐刘海挡住我们的内容)
我们简单演示一下:SliverGrid+SliverPadding+SliverSafeArea的组合
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: [
SliverSafeArea(
sliver: SliverPadding(
padding: EdgeInsets.all(9),
sliver: SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context,int index){
return Container(
alignment: Alignment(0, 0),
color: Colors.orange,
child: Text("item $index"),
);
},
childCount: 20
),
),
),
),
],
);
}
}
2. Slivers的组合使用
这里我使用官方的示例程序,将SliverAppBar+SliverGrid+SliverFixedExtentList做出如下界面:
class HomeContent extends StatelessWidget {
@override
Widget build(BuildContext context) {
return showCustomScrollView();
}
Widget showCustomScrollView() {
return CustomScrollView(
slivers: [
const SliverAppBar(
expandedHeight: 250,
flexibleSpace: FlexibleSpaceBar(
title: Text("My Demo"),
background: Image(
image: NetworkImage(
"https://tva1.sinaimg.cn/large/006y8mN6gy1g72j6nk1d4j30u00k0n0j.jpg"
),
fit: BoxFit.cover,
),
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 4.0
),
delegate: SliverChildBuilderDelegate(
(BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.teal[100*(index%9)],
child: Text("grid item $index"),
);
},
childCount: 10,
),
),
SliverFixedExtentList(
itemExtent: 50,
delegate: SliverChildBuilderDelegate(
(BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.orange[100*(index%9)],
child: Text("list item $index"),
);
},
childCount: 20
),
),
],
);
}
}
学习内容来自Flutter从入门到实战