文中所有示例代码请点击:gitee.com/yumi0629/Fl…

  今天呢,我小拉面主要想给大家讲一讲Flutter中的Slivers大家族的使用场景和方法。开发过列表布局的同学们应该对Slivers系列的控件不陌生,或多或少都用过这个库中的控件,来解决复杂的滑动嵌套布局。
  比如之前讲Hero的时候提到的下面这个界面,使用普通的GridView的话是没法实现的,我们选择使用CustomScrollView,然后在slivers属性中添加子控件,在这个例子里,我们可以用SliverToBoxAdapter来做HeaderView,GridView来做主体布局,整体为一个CustomScrollView,完全不会出现任何滑动冲突的问题。

  Flutter中的Slivers大家族基本都是配合CustomScrollView来实现的,除了上面提到的滑动布局嵌套,你还可以使用Slivers来实现页面头部展开/收起、 AppBar随手势变换等等功能。官方的Sliver库里面的控件很多,可以去Flutter API网站搜一下,这篇文章我只讲一些常用的控件。   OK, Let's start !!

SliverAppBar

  如果你是一名Android开发者,一定使用过CollapsingToolbarLayout这个布局来实现AppBar展开/收起的功能,在Flutter里面则对应SliverAppBar控件。给SliverAppBar设置flexibleSpaceexpandedHeight属性,就可以轻松完成AppBar展开/收起的功能:

CustomScrollView(slivers: <Widget>[SliverAppBar(actions: <Widget>[_buildAction(),],title: Text('SliverAppBar'),backgroundColor: Theme.of(context).accentColor,expandedHeight: 200.0,flexibleSpace: FlexibleSpaceBar(background: Image.asset('images/food01.jpeg', fit: BoxFit.cover),),// floating: floating,// snap: snap,// pinned: pinned,),SliverFixedExtentList(itemExtent: 120.0,delegate: SliverChildListDelegate(products.map((product) {return _buildItem(product);}).toList(),),),],);
复制代码

  如果设置floating属性为true,那么AppBar会在你做出下拉手势时就立即展开(即使ListView并没有到达顶部),该展开状态不显示flexibleSpace:   如果同时设置floatingsnap属性为true,那么AppBar会在你做出下拉手势时就立即全部展开(即使ListView并没有到达顶部),该展开状态显示flexibleSpace:

  如果不想AppBar消失,则设置pinned属性为true即可:

SliverList

  SliverList的使用非常简单,只需设置delegate属性即可,我们一般使用SliverChildBuilderDelegate,注意记得设置childCount,否则Flutter没法知道怎么绘制:

CustomScrollView(slivers: <Widget>[SliverList(delegate: SliverChildBuilderDelegate((BuildContext context, int index) {return _buildItem(context, products[index]);},childCount: 3,),)],);
复制代码

  你也可以通过下面的方式来设置childCount,如果不设置childCount,Flutter一旦发现delegate的某个index返回了null,就会认为childCount就是这个index。

delegate: SliverChildBuilderDelegate((BuildContext context, int index) {if(index>products.length){return null;}return _buildItem(context, products[index]);},
复制代码

  你也可以使用SliverChildListDelegate来构建delegate:

delegate: SliverChildListDelegate([_buildItem(),_buildItem(),_buildItem(),]),
复制代码

SliverChildListDelegateSliverChildBuilderDelegate的区别:

  • SliverChildListDelegate一般用来构item建数量明确的列表,会提前build好所有的子item,所以在效率上会有问题,适合item数量不多的情况(不超过一屏)。
  • SliverChildBuilderDelegate构建的列表理论上是可以无限长的,因为使用来lazily construct优化。 (两者的区别有些类似于ListView和ListView.builder()的区别。)

SliverGrid

  SliverGrid有三个构造函数:SliverGrid.count()SliverGrid.extentSliverGrid()

  • SliverGrid.count()指定了一行展示多少个item,下面的例子表示一行展示4个:
SliverGrid.count(children: scrollItems, crossAxisCount: 4)
复制代码
  • SliverGrid.extent可以指定item的最大宽度,然后让Flutter自己决定一行展示多少个item:
SliverGrid.extent(children: scrollItems, maxCrossAxisExtent: 90.0)
复制代码
  • SliverGrid()则是需要指定一个gridDelegate,它提供给了程序员一个自定义Delegate的入口,你可以自己决定每一个item怎么排列:
SliverGrid(gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: products.length,),delegate: SliverChildBuilderDelegate((BuildContext context, int index) {return _buildItem(products[index]);;}
);
复制代码

SliverPersistentHeader

  SliverPersistentHeader顾名思义,就是给一个可滑动的视图添加一个头(实际上,在CustomScrollView的slivers列表中,header可以出现在视图的任意位置,不一定要是在顶部)。这个Header会随着滑动而展开/收起,使用pinnedfloating属性来控制收起时Header是否展示(pinnedfloating属性不可以同时为true),pinnedfloating属性的具体意义和SliverAppBar中相同,这里就不再次解释了。

SliverPersistentHeader(pinned: pinned,floating: floating,delegate: _SliverAppBarDelegate(minHeight: 60.0,maxHeight: 180.0,child: Container(),),);
复制代码

  构建一个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;@overridedouble get minExtent => minHeight;@overridedouble get maxExtent => math.max(maxHeight, minHeight);@overrideWidget build(BuildContext context, double shrinkOffset, bool overlapsContent) {return new SizedBox.expand(child: child);}@overridebool shouldRebuild(_SliverAppBarDelegate oldDelegate) {return maxHeight != oldDelegate.maxHeight ||minHeight != oldDelegate.minHeight ||child != oldDelegate.child;}
}
复制代码

  写一个自定义SliverPersistentHeaderDelegate很简单,只需重写build()get maxExtentget minExtentshouldRebuild()这四个方法,上面就是一个最简单的SliverPersistentHeaderDelegate的实现。其中,maxExtent表示header完全展开时的高度,minExtent表示header在收起时的最小高度。因此,对于我们上面的那个自定义Delegate,如果将minHeightmaxHeight的值设置为相同时,header就不会收缩了,这样的Header跟我们平常理解的Header更像。
  之前也提到了,实际使用时,header不一定要放在slivers列表的最前面,可以随意混搭,当然,一般来说不会有这种视觉需求的:

CustomScrollView(slivers: <Widget>[_buildHeader(0),SliverGrid.count(crossAxisCount: 3,children: _products.map((product) {return _buildItemGrid(product);}).toList(),),_buildHeader(1),SliverFixedExtentList(itemExtent: 100.0,delegate: SliverChildListDelegate(products.map((product) {return _buildItemList(product);}).toList(),),),_buildHeader(2),SliverGrid(gridDelegate: new SliverGridDelegateWithMaxCrossAxisExtent(maxCrossAxisExtent: 200.0,mainAxisSpacing: 10.0,crossAxisSpacing: 10.0,childAspectRatio: 3.0,),delegate: new SliverChildBuilderDelegate((BuildContext context, int index) {return _buildItemGrid2(_products2[index]);},childCount: _products2.length,),),],);
复制代码

SliverToBoxAdapter

  SliverPersistentHeader一般来说都是会展开/收起的(除非minExtent和maxExtent值相同),那么如果想要在滚动视图中添加一个普通的控件,那么就可以使用SliverToBoxAdapter来将各种视图组合在一起,放在CustomListView中。

  上图中框起来的部分全部都是SliverToBoxAdapter,结合SliverToBoxAdapter,滚动视图可以任意组合:

CustomScrollView(physics: ScrollPhysics(),slivers: <Widget>[SliverToBoxAdapter(child: _buildHeader(),),SliverGrid.count(crossAxisCount: 3,children: products.map((product) {return _buildItemGrid(product);}).toList(),),SliverToBoxAdapter(child: _buildSearch(),),SliverFixedExtentList(itemExtent: 100.0,delegate: SliverChildListDelegate(products.map((product) {return _buildItemList(product);}).toList(),),),SliverToBoxAdapter(child: _buildFooter(),),],);
复制代码

Flutter:Slivers大家族,让滑动视图的组合变得很简单!相关推荐

  1. Flutter开发日常练习-pageview滑动视图动画

    养小猫咪的伙伴来我的店铺逛逛吧!抖音商城搜索#早睡早起的猫咪小铺子 学着写一下滑动页面 pageview实现左右滑动视图 class SlidingContainer extends Stateful ...

  2. Flutter Sliver大家族之SliverPersistentHeader()和SliverToBoxAdapter()组件(实现固定头布局)③

    Flutter Sliver大家庭之SliverPersistentHeade和SliverToBoxAdapter实现固定头布局③ SliverPersistentHeader SliverToBo ...

  3. Flutter Sliver大家族之SliverList(),SliverFixedExtentList(),SliverGrid()组件②

    Flutter Sliver大家族之SliverList,SliverFixedExtentList,SliverGrid组件② SliverFixedExtentList() SliverList( ...

  4. 导航组件—Android应用中使用ViewPager2创建滑动视图

    文章目录 一. 概述 二. 使用步骤 2.1 步骤一:在Activity或Fragment布局文件中添加ViewPager2 2.2 步骤二:创建ViewPager2每一个页面的视图Fragment ...

  5. 微信小程序中实现点击导航条切换页面(可左右滑动视图)

    我录制了个gif如下,黄色部分是不可以滑动的,蓝色部分可以滑动. 代码解说: 首先我在js自定义了navState参数用于判断导航的当前状态, 定义了data-index用于js中动态修改导航的当前状 ...

  6. swift 自定义滑动视图_在Swift中创建一个向上滑动菜单视图(以编程方式)

    swift 自定义滑动视图 This is a quick tutorial on how to create a slide-up menu view in iOS 这是有关如何在iOS中创建向上滑 ...

  7. androidstudio 日历视图怎么显示农历_中秋国庆旅游攻略怎么做?用这个便签软件很简单...

    九月已经到来,中秋节和国庆节距离我们也不远了,今年的中秋和国庆节重叠了有足足八天的假期.不少人都想趁着这个小长假出门旅游,要想保证旅游质量,那么就要做好攻略.中秋国庆旅游攻略怎么做? 要想做好一份中秋 ...

  8. aqara (737) -(a俩)_A-史密斯:勇士有人类已知的最强后场组合,湖人很难限制

    虎扑11月7日讯 今日,NBA评论员斯蒂芬-A-史密斯在<First Take>节目中谈到了他对于新赛季的勇士的期待.节目未上线前史密斯曾与节目官方推特互动预热,称后场投射最强的那支球队更 ...

  9. ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程

    ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 原文:ASP.NET Core Razor 布局视图 - ASP.NET Core 基础 ...

  10. 组合恒等式1 五个基本的组合恒等式 基础与简单例子

    组合恒等式1 五个基本的组合恒等式 基础与简单例子 四个基本的组合恒等式 应用四个基本恒等式计算组合恒等式的例题 应用四个基本恒等式证明组合恒等式的例题 组合恒等式是组合学中一个非常有趣但也十分具有挑 ...

最新文章

  1. Java 学习笔记 ------第二章 从JDK到IDE
  2. 初涉网络实验-路由器端口的开启与配置
  3. 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?...
  4. 详解JavaScript中ES5和ES6的类、继承之间区别和联系
  5. git add .出现尚未暂存以备提交的变更
  6. Linux篇 | 多网卡绑定技术 binding 和 网络组nmcli
  7. C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
  8. VS2017 调用Tesseract
  9. 关于JS闭包,作者不详(转)
  10. AVAssetWriter写入char*数据(video)
  11. 数据类型选方法【SPSS 073期】
  12. iphone 目录大全
  13. 高德地图提示com.autonavi.amap.mapcore.MapCore.nativeNewInstance问题
  14. 给SLAM小车添加 手柄遥控 功能 罗技F710和PS4 手柄
  15. 创客使用Fusion 360 - 制作模型
  16. AutoCAD2006软件下载AutoCAD2006安装方法
  17. 你还记得当年高考时的样子吗?
  18. 25.mc_api介绍及使用示例
  19. 企业各职位英文缩写 PM,TM,PL,TL,SE,PG,CEO,CFO
  20. 独立之精神,自由之思想

热门文章

  1. vue-cli中的babel配置文件.babelrc详解
  2. RUP---统一软件开发过程
  3. 封装一个帮助类来写文件到android外置存储器上
  4. 最简单的三层实例【插入据
  5. 常用工具下载及在线地址
  6. DRmare Audio Converter Mac使用指南 - DRM音频清除转换
  7. Mac电脑设置鼠标主按钮的方法?
  8. cargo 使用国内源镜像,引用 substrate 的 Contracts Pallet Crate 编译错误
  9. NSTimer 的正确用法你真的知道吗?
  10. 十进制转化八进制,十六进制