Flutter---Sliver集合

Flutter—Sliver家族系列

核心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,
          )
  1. expandedHeight: 最大扩展高度
  2. flexibleSpace: 扩展内容区域
  3. floating: 为true则在滚动时优先滚动,有下拉动作先appbar后flexibleSpace,反之亦然
  4. snap: 为true时没有变化,正在查证
  5. pinned:为true则appbar不消失,在下拉时会多划出一段距离SliverAppBar才开始滚动

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('可伸缩头部--位置随意'),
                  ),
                )
            ),
          )
  1. floating: 为 true 时,与SliverAppBar用法一致
  2. pinned:与SliverAppBar用法一致,且与floating不能同时为true
  3. delegate: 构建一个SliverPersistentHeader需要传入一个delegate,这个delegate是SliverPersistentHeaderDelegate类型的,而SliverPersistentHeaderDelegate是一个abstract类,我们不能直接new一个SliverPersistentHeaderDelegate出来,因此,我们需要自定义一个delegate来实现SliverPersistentHeaderDelegate类,如下例:
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'),),
              ]),
            ),
          )

暂时告一段落,本文学习于吉原拉面

你可能感兴趣的:(flutter)