核心CustomScrollView
CustomScrollView是可以使用各种sliver来实现各种酷炫的滚动效果,它的slivers属性里可以放置各种sliver组件。
1.SliverAppBar
SliverAppBar 是一个可伸缩的头部,可以实现上拉收起,下拉展开效果,如下例:
SliverAppBar(
leading: Icon(Icons.arrow_back_ios),
title: Text('伸缩头部'),
actions: [
IconButton(icon: Icon(Icons.android), onPressed: (){}),
IconButton(icon: Icon(Icons.print), onPressed: (){}),
],
backgroundColor: Theme.of(context).accentColor,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
background: Image.network('http://k.zol-img.com.cn/sjbbs/7692/a7691515_s.jpg', fit: BoxFit.cover,),
),
floating: true,
snap: false,
pinned: true,
)
2.SliverPersistentHeader
SliverPersistentHeader有点类似SliverAppBar,同样可以收起和展开,可以放置到slivers任何一个位置,如下例:
SliverPersistentHeader(
floating: false,//floating 与pinned 不能同时为true
pinned: true,
delegate: _SliverAppBarDelegate(
minHeight: 50.0,
maxHeight: 200.0,
child: Container(
color: Colors.lightBlue,
child: Center(
child: Text('可伸缩头部--位置随意'),
),
)
),
)
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
_SliverAppBarDelegate({
@required this.minHeight,
@required this.maxHeight,
@required 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;
}
}
写一个自定义SliverPersistentHeaderDelegate很简单,只需重写build()、get maxExtent、get minExtent和shouldRebuild()这四个方法,上面就是一个最简单的SliverPersistentHeaderDelegate的实现。其中,maxExtent表示header完全展开时的高度,minExtent表示header在收起时的最小高度。因此,对于我们上面的那个自定义Delegate,如果将minHeight和maxHeight的值设置为相同时,header就不会收缩了,这样的Header跟我们平常理解的Header更像。
SliverList
SliverList类似ListView,他有两种表现形式:SliverChildBuilderDelegate和SliverChildListDelegate,两者区别在于SliverChildBuilderDelegate可以加载不确定数量的列表,而SliverChildListDelegate只能加载固定已知数量。
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index){
return ListTile(title: Text('高度不固定${index+1}'),);
}, childCount: 10),
)
SliverList(
delegate: SliverChildListDelegate([
ListTile(title: Text('固定条数1'),),
ListTile(title: Text('固定条数2'),),
ListTile(title: Text('固定条数3'),),
]),
)
SliverFixedExtentList
SliverFixedExtentList与SliverList类似,唯一区别是SliverFixedExtentList可以设置固定高度。
SliverFixedExtentList(
itemExtent: 60.0,
delegate: SliverChildBuilderDelegate((BuildContext context, int index){
return ListTile(title: Text('高度固定${index+1}'),);
}, childCount: 10),
)
SliverGrid
SliverGrid 可以设置固定一行显示几个SliverGridDelegateWithFixedCrossAxisCount,也可以SliverGridDelegateWithMaxCrossAxisExtent设置子元素最大宽度,让flutter决定一行几个。count和extent就是封装方法。
SliverGrid(
delegate: SliverChildBuilderDelegate((BuildContext context, int index){
return ListTile(title: Text('slivergird'),);
}, childCount: 10),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, childAspectRatio: 8.0),
// gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 20, ),
)
SliverGrid.count(
crossAxisCount: 3,
childAspectRatio: 1.0,
children: [
ListTile(title: Text('固定条数1'),),
ListTile(title: Text('固定条数2'),),
ListTile(title: Text('固定条数3'),),
ListTile(title: Text('固定条数1'),),
ListTile(title: Text('固定条数2'),),
ListTile(title: Text('固定条数3'),),
],
)
SliverGrid.extent(
maxCrossAxisExtent: 200.0,
childAspectRatio: 8.0,
children: [
Container(child: Text('自由扩展')),
Container(child: Text('自由扩展')),
Container(child: Text('自由扩展')),
Container(child: Text('自由扩展')),
Container(child: Text('自由扩展')),
Container(child: Text('自由扩展')),
],
)
SliverToBoxAdapter
SliverToBoxAdapter的child属性可以加载普通widget组件
SliverToBoxAdapter(
child: TextField(decoration: InputDecoration(hintText: '普通widget'),),
)
SliverPadding
SliverPadding可以设置padding,子widget为sliver
SliverPadding(
padding: EdgeInsets.all(10.0),
sliver: SliverList(
delegate: SliverChildListDelegate([
ListTile(title: Text('固定条数1'),),
ListTile(title: Text('固定条数2'),),
ListTile(title: Text('固定条数3'),),
]),
),
)
暂时告一段落,本文学习于吉原拉面