Flutter:Slivers大家族,让滑动视图的组合变得很简单!
文中所有示例代码请点击: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
设置flexibleSpace
和expandedHeight
属性,就可以轻松完成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: 如果同时设置floating
和snap
属性为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(),]),
复制代码
SliverChildListDelegate
和SliverChildBuilderDelegate
的区别:
- SliverChildListDelegate一般用来构item建数量明确的列表,会提前build好所有的子item,所以在效率上会有问题,适合item数量不多的情况(不超过一屏)。
- SliverChildBuilderDelegate构建的列表理论上是可以无限长的,因为使用来lazily construct优化。 (两者的区别有些类似于ListView和ListView.builder()的区别。)
SliverGrid
SliverGrid
有三个构造函数:SliverGrid.count()
、SliverGrid.extent
和SliverGrid()
。
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会随着滑动而展开/收起,使用pinned
和floating
属性来控制收起时Header是否展示(pinned
和floating
属性不可以同时为true
),pinned
和floating
属性的具体意义和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 maxExtent
、get minExtent
和shouldRebuild()
这四个方法,上面就是一个最简单的SliverPersistentHeaderDelegate的实现。其中,maxExtent
表示header完全展开时的高度,minExtent
表示header在收起时的最小高度。因此,对于我们上面的那个自定义Delegate,如果将minHeight
和maxHeight
的值设置为相同时,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大家族,让滑动视图的组合变得很简单!相关推荐
- Flutter开发日常练习-pageview滑动视图动画
养小猫咪的伙伴来我的店铺逛逛吧!抖音商城搜索#早睡早起的猫咪小铺子 学着写一下滑动页面 pageview实现左右滑动视图 class SlidingContainer extends Stateful ...
- Flutter Sliver大家族之SliverPersistentHeader()和SliverToBoxAdapter()组件(实现固定头布局)③
Flutter Sliver大家庭之SliverPersistentHeade和SliverToBoxAdapter实现固定头布局③ SliverPersistentHeader SliverToBo ...
- Flutter Sliver大家族之SliverList(),SliverFixedExtentList(),SliverGrid()组件②
Flutter Sliver大家族之SliverList,SliverFixedExtentList,SliverGrid组件② SliverFixedExtentList() SliverList( ...
- 导航组件—Android应用中使用ViewPager2创建滑动视图
文章目录 一. 概述 二. 使用步骤 2.1 步骤一:在Activity或Fragment布局文件中添加ViewPager2 2.2 步骤二:创建ViewPager2每一个页面的视图Fragment ...
- 微信小程序中实现点击导航条切换页面(可左右滑动视图)
我录制了个gif如下,黄色部分是不可以滑动的,蓝色部分可以滑动. 代码解说: 首先我在js自定义了navState参数用于判断导航的当前状态, 定义了data-index用于js中动态修改导航的当前状 ...
- swift 自定义滑动视图_在Swift中创建一个向上滑动菜单视图(以编程方式)
swift 自定义滑动视图 This is a quick tutorial on how to create a slide-up menu view in iOS 这是有关如何在iOS中创建向上滑 ...
- androidstudio 日历视图怎么显示农历_中秋国庆旅游攻略怎么做?用这个便签软件很简单...
九月已经到来,中秋节和国庆节距离我们也不远了,今年的中秋和国庆节重叠了有足足八天的假期.不少人都想趁着这个小长假出门旅游,要想保证旅游质量,那么就要做好攻略.中秋国庆旅游攻略怎么做? 要想做好一份中秋 ...
- aqara (737) -(a俩)_A-史密斯:勇士有人类已知的最强后场组合,湖人很难限制
虎扑11月7日讯 今日,NBA评论员斯蒂芬-A-史密斯在<First Take>节目中谈到了他对于新赛季的勇士的期待.节目未上线前史密斯曾与节目官方推特互动预热,称后场投射最强的那支球队更 ...
- ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程
ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 原文:ASP.NET Core Razor 布局视图 - ASP.NET Core 基础 ...
- 组合恒等式1 五个基本的组合恒等式 基础与简单例子
组合恒等式1 五个基本的组合恒等式 基础与简单例子 四个基本的组合恒等式 应用四个基本恒等式计算组合恒等式的例题 应用四个基本恒等式证明组合恒等式的例题 组合恒等式是组合学中一个非常有趣但也十分具有挑 ...
最新文章
- Java 学习笔记 ------第二章 从JDK到IDE
- 初涉网络实验-路由器端口的开启与配置
- 为什么使用消息队列? 消息队列有什么优点和缺点? Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别,以及适合哪些场景?...
- 详解JavaScript中ES5和ES6的类、继承之间区别和联系
- git add .出现尚未暂存以备提交的变更
- Linux篇 | 多网卡绑定技术 binding 和 网络组nmcli
- C#Winform窗体实现服务端和客户端通信例子(TCP/IP)
- VS2017 调用Tesseract
- 关于JS闭包,作者不详(转)
- AVAssetWriter写入char*数据(video)
- 数据类型选方法【SPSS 073期】
- iphone 目录大全
- 高德地图提示com.autonavi.amap.mapcore.MapCore.nativeNewInstance问题
- 给SLAM小车添加 手柄遥控 功能 罗技F710和PS4 手柄
- 创客使用Fusion 360 - 制作模型
- AutoCAD2006软件下载AutoCAD2006安装方法
- 你还记得当年高考时的样子吗?
- 25.mc_api介绍及使用示例
- 企业各职位英文缩写 PM,TM,PL,TL,SE,PG,CEO,CFO
- 独立之精神,自由之思想