Flutter 之 Sliver 系列控件

SliverAppBar

SliverAppBar 控件,一个 MD 的 AppBar 。属性和 AppBar 类似,但做的效果比 AppBar 更加强大。相同的属性具体可以看 Flutter 之 Scaffold 控件 , 里面有 AppBar 控件的介绍。那么还有些没有的属性:

属性

  • forceElevated

结合 elevation 使用,当elevation 不为 0 的时候,是否显示阴影

  • expandedHeight

AppBar 展开时候的高度

  • floating

true 的时候下滑AppBar优先滑动展示,展示完成后才给滑动控件滑动

  • snap

snap 为 true, 则 floating 也要为 true 。true 的时候根据手指松开的位置展开或者收缩AppBar

  • pinned

appBar 收缩到最小高度的时候 appBar 是否可见

用法

SliverAppBar 往往做为 CustomScrollView 的第一个子元素,根据滚动控件的偏移量或者浮动的位置来改变 SliverAppBar 的高度。所以具体用法如下

class _MyHomePageState extends State {
  ScrollController _scrollController;
  VoidCallback onChange;

  @override
  void initState() {
    super.initState();
    _scrollController = ScrollController();
    onChange = () {
      print('onChange');
    };
    _scrollController.addListener(onChange);
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: new CustomScrollView(
        //滚动方向
        scrollDirection: Axis.vertical,
        //是否反转滚动方向
        reverse: false,
        //监听事件等等控制器
        controller: _scrollController,
        //true 的话 controller 一定要为null
        primary: false,
        //滑动效果,如阻尼效果等等
        physics: const BouncingScrollPhysics(),
        //滑动控件是否在头部上面滑过去
        shrinkWrap: false,
        //0到1之间,到顶部的距离
        anchor: 0.0,
        //“预加载”的区域,0.0 为关闭预加载
        cacheExtent: 0.0,
        slivers: [
          SliverAppBar(
            elevation: 5,
            forceElevated: true,
            expandedHeight: 250.0,
            floating: true,
            snap: true,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: const Text('SliverAppBar'),
              background: Image.network(
                'https://cn.bing.com/th?id=OIP.xq1C2fmnSw5DEoRMC86vJwD6D6&pid=Api&rs=1',
                fit: BoxFit.fill,
              ),
              //标题是否居中
              centerTitle: true,
              //标题间距
              titlePadding: EdgeInsetsDirectional.only(start: 0, bottom: 16),
              collapseMode: CollapseMode.none,
            ),
          ),
        ],
        semanticChildCount: 6,//可见子元素的总数
      ),
    );
  }
}

另外在上面设计到 FlexibleSpaceBar 控件,FlexibleSpaceBar 有个 collapseMode 属性

  • CollapseMode.none 背景不随着滚动
  • CollapseMode.parallax 背景滚动具有视差效果
  • CollapseMode.pin 背景随着滚动,并且手指松开的时候根据松开位置进行展开收缩 AppBar 。

SliverPadding

为 Sliver 系列控件添加一个 padding 。如给上面 SliverAppBar 添加一个 Padding 。

SliverPadding(
            padding: EdgeInsets.all(10.0),
            sliver: SliverAppBar(...),
            ),
          )
AppBar效果.png

SliverGrid

多行多列的列表控件,相当于 Android 的 GridView,有两个属性

  • delegate

SliverChildDelegate,这里有两种方式创建

  • SliverChildListDelegate 一般用来构 item 不多的列表,效率更低。
List _gridLists = ['grid item 1','grid item 2','grid item 3','grid item 4','grid item 5'];

delegate: SliverChildListDelegate(
                  _gridLists.map((name){
                    return new Container(
                      alignment: Alignment.center,
                      color: Colors.blue,
                      child: new Text(name),
                    );
                  }).toList()
              ),
  • SliverChildBuilderDelegate 一般用来构 item 更多的列表,效率更高。
delegate: new SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  //创建子widget
                  return new Container(
                    alignment: Alignment.center,
                    color: Colors.blue,
                    child: new Text('grid item $index'),
                  );
                },
                childCount: 20,
              ),
  • gridDelegate

SliverGridDelegate,也是有两种方式创建

  • SliverGridDelegateWithMaxCrossAxisExtent,根据给的 maxCrossAxisExtent 最大宽度自动分配一列展示多少个。
gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 150,
                mainAxisSpacing: 10.0, //主轴中间间距
                crossAxisSpacing: 10.0, //副轴中间间距
                childAspectRatio: 2.0, //item 宽高比
              ),
  • SliverGridDelegateWithFixedCrossAxisCount,固定展示多少列。
gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4,
                mainAxisSpacing: 10.0, //主轴中间间距
                crossAxisSpacing: 10.0, //副轴中间间距
                childAspectRatio: 2.0, //item 宽高比
              )

结合上面展示效果

image.png

SliverList

和上面 delegate 属性一样,需要创建一个 SliverChildDelegate 。

new SliverList(
            delegate: new SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  //创建列表项
                  return new Container(
                    height: 50,
                    alignment: Alignment.center,
                    color: Colors.lightBlue[100 * ((index % 9) + 1)],
                    child: new Text('list item $index'),
                  );
                }, childCount: 30 //30个列表项
            ),
          ),
image.png

SliverFixedExtentList

比 SliverList 多一个 itemExtent 属性,设置 item 的高度 。item 里面的子控件无法再改动高度。

SliverPersistentHeader

上面 SliverAppBar 就是结合 SliverPersistentHeader 实现的效果,SliverPersistentHeader 需要一个 SliverPersistentHeaderDelegate 。 实现 SliverPersistentHeaderDelegate 有 4 个方法需要重写

class SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    // TODO: implement build
    return null;
  }
  @override
  // TODO: implement maxExtent
  double get maxExtent => null;

  @override
  // TODO: implement minExtent
  double get minExtent => null;

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    // TODO: implement shouldRebuild
    return null;
  }
}

至于效果,具体效果具体分析。

SliverToBoxAdapter

有一个 Widget 属性,主要作用是在 CustomScrollView 里面添加多种不同布局的样式。

new SliverToBoxAdapter(
            child: Container(
              height: 100,
              child: Text('SliverToBoxAdapter'),
            ),
          ),

SliverFillViewport

占满一屏或者比一屏更多的布局,

new SliverFillViewport(
              delegate:new SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                    //创建列表项
                    return new Container(
                      alignment: Alignment.center,
                      color: Colors.lightBlue,
                      child: new Text('SliverFillViewport'),
                    );
                  }, childCount: 1
              ),
              viewportFraction:1.0,//占屏幕的比例
          ),

SliverFillRemaining

滑动剩余部分展示的布局

你可能感兴趣的:(Flutter 之 Sliver 系列控件)