简介

在上一篇文章我们讲解SliverAppBar的时候有提到过,Sliver的组件一般都用在CustomScrollView中。除了SliverAppBar之外,我们还可以为CustomScrollView添加List或者Grid来实现更加复杂的组合效果。

今天要向大家介绍的就是SliverList和SliverGird。

SliverList和SliverGird详解

从名字就可以看出SliverList和SliverGird分别是List和Grid的一种,他们和List与Grid最大的区别在于,他们可以控制子widget在main axis和cross axis之间的间隔,并且可以通过Extent属性来控制子widget的大小,非常的强大。

我们先来看下这两个组件的定义和构造函数:

class SliverList extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver that places box children in a linear array.
const SliverList({
Key? key,
required SliverChildDelegate delegate,
}) : super(key: key, delegate: delegate);

SliverList继承自SliverMultiBoxAdaptorWidget,它的构造函数比较简单,需要传入一个SliverChildDelegate的参数,这里的SliverChildDelegate使用的是delegate的方法来创建SliverList的子组件。

SliverChildDelegate是一个抽象类,它有两个实现类,分别是SliverChildBuilderDelegate和SliverChildListDelegate。

其中SliverChildBuilderDelegate是用的builder模式来生成子widget,在上一篇文章中,我们构建SliverList就是使用的这个builder类。

SliverChildBuilderDelegate使用builder来生成子Widget,而SliverChildListDelegate需要传入一个childList来完成构造,也就是说SliverChildListDelegate需要一个确切的childList,而不是用builder来构建。

要注意的是SliverList并不能指定子widget的extent大小,如果你想指定List中的子widget的extent大小的话,那么可以使用SliverFixedExtentList:

class SliverFixedExtentList extends SliverMultiBoxAdaptorWidget {
const SliverFixedExtentList({
Key? key,
required SliverChildDelegate delegate,
required this.itemExtent,
}) : super(key: key, delegate: delegate);

可以看到SliverFixedExtentList和SliverList相比,多了一个itemExtent参数,用来控制子widget在main axis上的大小。

然后我们再来看一下SliverGird:

class SliverGrid extends SliverMultiBoxAdaptorWidget {
/// Creates a sliver that places multiple box children in a two dimensional
/// arrangement.
const SliverGrid({
Key? key,
required SliverChildDelegate delegate,
required this.gridDelegate,
}) : super(key: key, delegate: delegate);

SliverGrid也是继承自SliverMultiBoxAdaptorWidget,和SliverList一样,它也有一个SliverChildDelegate的参数,另外它还多了一个gridDelegate的参数用来控制gird的布局。

这里的gridDelegate是一个SliverGridDelegate类型的参数,用来控制children的size和position。

SliverGridDelegate也是一个抽象类,它有两个实现类,分别是SliverGridDelegateWithMaxCrossAxisExtent和SliverGridDelegateWithFixedCrossAxisCount,这两个实现类的区别就在于MaxCrossAxisExtent和FixedCrossAxisCount的区别。

怎么理解MaxCrossAxisExtent呢?比如说这个Grid是竖向的,然后Gird的宽度是500.0,如果MaxCrossAxisExtent=100,那么delegate将会创建5个column,每个column的宽度是100。

crossAxisCount则是直接指定cross axis的child个数有多少。

SliverList和SliverGird的使用

有了上面介绍的SliverList和SliverGird的构造函数,接下来我们具体来看下如何在项目中使用SliverList和SliverGird。

默认情况下SliverList和SliverGird是需要和CustomScrollView一起使用的,所以我们先创建一个CustomScrollView,在它的slivers属性中,放入一个SliverAppBar组件:

CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: true,
snap: false,
floating: false,
expandedHeight: 200.0,
flexibleSpace: FlexibleSpaceBar(
title: Text('SliverList and SliverGrid'),
),
),
],
);

SliverAppBar只是一个AppBar,运行可以得到下面的界面:

我们还需要为它继续添加其他的slivers组件。

首先给他添加一个SliverGrid:

SliverGrid(
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 20.0,
crossAxisSpacing: 50.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.green[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 20,
),
),

这里我们设置了gridDelegate属性,并且自定义了SliverChildBuilderDelegate,用来生成20个Container。

运行得到的界面如下:

然后为其添加SliverList:

SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: index.isOdd ? Colors.white : Colors.green,
height: 50.0,
child: Center(
child: ListTile(
title: Text(
'100' + index.toString(),
style: const TextStyle(fontWeight: FontWeight.w500),
),
leading: Icon(
Icons.account_box,
color: Colors.green[100 * (index % 9)],
),
),
),
);
},
childCount: 15,
),
),

因为SliverList只需要传入一个delegate参数,这里我们生成了15个child组件。生成的界面如下:

因为SliverList不能控制List中子widget的extent,所以我们再添加一个SliverFixedExtentList看看效果:

SliverFixedExtentList(
itemExtent: 100.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: index.isOdd ? Colors.white : Colors.green,
height: 50.0,
child: Center(
child: ListTile(
title: Text(
'200' + index.toString(),
style: const TextStyle(fontWeight: FontWeight.w500),
),
leading: Icon(
Icons.account_box,
color: Colors.green[100 * (index % 9)],
),
),
),
);
},
childCount: 15,
),

SliverFixedExtentList和SliverList相比多了一个itemExtent属性,这里我们将其设置为100,运行可以得到下面的界面:

可以看到List中的子Widget高度发生了变化。

总结

在CustomScrollView中使用SliverList和SliverGird,可以实现灵活的呈现效果。

本文的例子:https://github.com/ddean2009/learn-flutter.git

flutter系列之:使用SliverList和SliverGird的更多相关文章

  1. Flutter系列博文链接

    Flutter系列博文链接 ↓: Flutter基础篇: Flutter基础篇(1)-- 跨平台开发框架和工具集锦 Flutter基础篇(2)-- 老司机用一篇博客带你快速熟悉Dart语法 Flutt ...

  2. flutter系列之:UI layout简介

    目录 简介 flutter中layout的分类 常用layout举例 总结 简介 对于一个前端框架来说,除了各个组件之外,最重要的就是将这些组件进行连接的布局了.布局的英文名叫做layout,就是用来 ...

  3. flutter系列之:如丝般顺滑的SliverAppBar

    目录 简介 SliverAppBar详解 SliverAppBar的使用 总结 简介 对于一个APP来说,肯定会有一个AppBar,这个AppBar一般包含了APP的导航信息等.虽然我们可以用一个固定 ...

  4. flutter系列之:flutter架构什么的,看完这篇文章就全懂了

    目录 简介 Flutter的架构图 embedder engine Flutter framework Widgets Widgets的可扩展性 Widgets的状态管理 渲染和布局 总结 简介 Fl ...

  5. flutter系列之:widgets,构成flutter的基石

    目录 简介 StatelessWidget和StatefulWidget StatelessWidget详解 StatefulWidget详解 总结 简介 flutter中所有的组件都是由widget ...

  6. flutter系列之:用来管理复杂状态的State详解

    目录 简介 StatefuWidget和State State的生命周期 总结 简介 Flutter的基础是widget,根据是否需要跟用户进行交互,widget则可以分为StatelessWidge ...

  7. flutter系列之:构建Widget的上下文环境BuildContext详解

    目录 简介 BuildContext的本质 BuildContext和InheritedWidget BuildContext的层级关系 总结 简介 我们知道Flutter中有两种Widget,分别是 ...

  8. flutter系列之:移动端的手势基础GestureDetector

    目录 简介 Pointers和Listener GestureDetector 手势冲突 总结 简介 移动的和PC端有什么不同呢?同样的H5可以运行在APP端,也可以运行在PC端.两者最大的区别就是移 ...

  9. flutter系列之:Material主题的基础-MaterialApp

    简介 为了简化大家的使用,虽然flutter推荐所有的widget都有自己来进行搭建,但是在大框架上面,flutter提供了Material和Cupertino两种主题风格的Widgets集合,大家可 ...

  10. flutter系列之:flutter中常用的container layout详解

    目录 简介 Container的使用 旋转Container Container中的BoxConstraints 总结 简介 在上一篇文章中,我们列举了flutter中的所有layout类,并且详细介 ...

随机推荐

  1. 1742C

    题目链接 题目大意: 在一个8x8的方格中你每次可以将一行全部涂成红色或者将一列涂成蓝色.问最后一次操作是什么操作: 如果是行操作就输出R 如果是列操作就输出B 解题思路: 我们可一枚举每行每列,如果 ...

  2. nginx日志切割并备份

    [root@lecode-pre55 bin]# cat nginx-log.sh #!bin/bash #auther:ansheng #desc: nginx日志备份,注意脚本中文件的路径. #备 ...

  3. Kubernetes IPVS和IPTABLES

    个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github‍:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying Kubernetes IPVS和IPTABLES ...

  4. 简单的sql注入3

    仍然 1 1' 1" 发现1'报错了.....我觉得作者对'情有独钟 再试试 1# 1'# 1"# 发现都可以正常登录 试试1' and '1'='1和1' and '1'='2发 ...

  5. 树莓派蓝牙rfcomm协议通信

    修改配置文件 手机使用 "蓝牙串口" 软件,树莓派上修改文件/etc/systemd/system/dbus-org.bluez.service ExecStart=/usr/li ...

  6. 记一次windows10电脑连上wifi无法上网的解决问题

    前言 今天下午同学的电脑能连上wifi,但是却上不了互联网 开始思考 首先想到的肯定是WiFi驱动问题,但是wifi能连上大部分的原因可能就不是驱动问题了,为了彻底排除这个因素,我用到了我的usb网卡 ...

  7. day13 I/O流——字节输入输出流、字符输入输出流 & File常用类 & (字节)复制大文件

    day13 I/O流 定义:数据在两设备传输称为流,流是一组有顺序的,有起点和终点的字节集合 I 是input的缩写,表示输入流 O是output缩写,表示输出流 字节流(视频等) 输入InputSt ...

  8. ArcObjects SDK开发 010 FeatureLayer

    1.FeatureLayer的结构 FeatureLayer是我们开发的时候用的最多的API之一,其实现的接口以及关联的其他API也非常多.下面我们就用一张图来整体看下FeatureLayer有哪些常 ...

  9. 【Phoenix】简介、架构、存储、入门、常用表操作、表的映射方式、配置二级索引

    一.Phoenix简介 1.定义 构建在 HBase 之上的开源 SQL 层 可以使用标准的 JDBC API 去建表, 插入数据和查询 HBase 中的数据 避免使用 HBase 的客户端 API ...

  10. LeetCode HOT 100:下一个排列

    题目:31. 下一个排列 题目描述: 本题是给你一个整数数组,返回该数组的下一个线性顺序排列. 举个例子:给你一个[1, 2, 3]的数组,他的线性排列顺序从小到大依次为[1, 3, 2],[2, 1 ...