Flutter GridView 网格控件
在项目中,有时候会有诸如“日历”展示之类的需求,此时单列表ListView控件已经无法满足我们的需要。GridView就是为了满足这样的“二维数组”排列而存在的。
1、默认构造函数
GridView({
//与ListView相同的参数
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
double cacheExtent,
//GridView特有属性
@required SliverGridDelegate gridDelegate, //控制子widget layout的委托
List<Widget> children = const <Widget>[],
})
GridView的大部分参数与ListView是一样的,请参见系列文章《Flutter ListView 列表控件》。
我们需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。
SliverGridDelegate是一个抽象类,定义了GridView Layout相关接口。Flutter中提供了两个子类:SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent,我们可以直接使用。
2、SliverGridDelegateWithFixedCrossAxisCount
属性值 |
含义 |
---|---|
crossAxisCount |
决定有网格有多少列数据 |
mainAxisSpacing |
主轴方向item之间的间隙 |
crossAxisSpacing |
非主轴方向item之间的间隙 |
childAspectRatio |
非主轴方向的item内容与主轴方向的内容宽高比默认=1.0(即1:1展示) |
@required this.crossAxisCount,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.childAspectRatio = 1.0,
2.1、举例说明:
假设需要实现一个3列的网格(只需要固定列,行数可根据数据多少自动调节),主轴方向item间隙为20像素,非主轴方向的item间隙为10像素,非主轴方向的内容是主轴方向内容的2倍容量。我们可以这样实现:
body: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
mainAxisSpacing: 20,
crossAxisSpacing: 10,
childAspectRatio: 2,
),
children: <Widget>[
Container(
color: Colors.green,
child: Icon(Icons.ac_unit),
),
//……此处省略7个Icon代码
Container(
color: Colors.green,
child: Icon(Icons.accessible_forward),
),
],
),
Icon外面包裹Container控件是为了设置背景颜色,让效果更直观。
效果如下:
3、SliverGridDelegateWithMaxCrossAxisExtent
属性值 |
含义 |
---|---|
maxCrossAxisExtent |
决定每一列的item占用多少像素 |
mainAxisSpacing |
主轴方向item之间的间隙 |
crossAxisSpacing |
非主轴方向item之间的间隙 |
childAspectRatio |
非主轴方向的item内容与主轴方向的内容宽高比默认=1.0(即1:1展示) |
@required this.maxCrossAxisExtent,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
this.childAspectRatio = 1.0,
mainAxisSpacing、crossAxisSpacing、childAspectRatio三个参数与SliverGridDelegateWithFixedCrossAxisCount相同,这里我们主要理解maxCrossAxisExtent
的用法。
- maxCrossAxisExtent
此参数表示每一列的item占用多少像素的宽度。假设非主轴(横轴)的总像素是500,那么mainAxisSpacing = 100
表示每行可展示5列(前提是设置item间隙)。因此,可以通过控制mainAxisSpacing
的值来动态控制网格布局的列数。
3.1、举例说明:
假设将maxCrossAxisExtent设为80,主轴方向item间隙为10像素,非主轴方向的item间隙为10像素,非主轴方向的内容是主轴方向内容的2倍容量。我们可以这样实现:
body: GridView(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 80,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 2,
),
children: <Widget>[
Container(
color: Colors.green,
child: Icon(Icons.ac_unit),
),
//……此处省略7个Icon代码
Container(
color: Colors.green,
child: Icon(Icons.accessible_forward),
),
],
),
效果如下:
可以看出网格布局变成了5列,通过计算80*5+10*4=440px
得出使用宽度为440像素,剩下60像素不足以再多出一列的宽度,所以最多只能生成5列数据。
4、GridView.extent
GridView.extent
是SliverGridDelegateWithMaxCrossAxisExtent
的另一种代码表现形式(大概是因为名字太长了),它们具有相同的功能。
用法:
body: GridView.extent(
maxCrossAxisExtent: 80,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 2,
5、GridView.builder
以上GridView都需要事先排列好所有的item布局(widget),这就相当于将数据提前写死了,不方便动态拓展,也不适合数据过多的情况。当子widget比较多时,我们可以通过GridView.builder来动态创建子widget。
GridView.builder(gridDelegate: null, itemBuilder: null),
gridDelegate参数在上面已经讲过了,我们主要来看看itemBuilder
如何使用。
5.1、举例说明:
设置一个网格布局,拥有50个子项目,前10个项目输出索引,拥有绿色背景,之后所有项目拥有蓝色背景。
child: GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 100,
mainAxisSpacing: 10,
crossAxisSpacing: 10,
childAspectRatio: 2,
),
itemCount: 50,
itemBuilder: (BuildContext context, int position) {
Widget item;
if (position < 10) {
item = FlatButton.icon(
icon: Icon(Icons.info),
label: Text("" + position.toString()),
color: Colors.green,
onPressed: () {},
);
} else {
item = Container(
color: Colors.blue,
child: Icon(
Icons.airplanemode_active,
color: Colors.white,
),
);
}
return item;
}),
注意:itemCount
虽然不是必选参数,实际使用时别忘记加上,它是决定子项显示数量的关键因素。
效果如下:
6、StaggeredGridView.countBuilder 瀑布流
StaggeredGridView不是Flutter提供的GridView组件,而是专门为实现瀑布流而存在的flutter_staggered_grid_view
包提供的功能。
6.1、使用步骤:
- 导入flutter_staggered_grid_view库。
pubspec.yaml
文件中导入如下代码:
dependencies:
# 瀑布流
flutter_staggered_grid_view: ^0.2.7
- 导入包到代码文件
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
- 使用
StaggeredGridView.countBuilder(
mainAxisSpacing: 4.0,
crossAxisSpacing: 4.0,
crossAxisCount: 4,
itemCount: 20,
itemBuilder: (BuildContext context, int index) => new Container(
color: index.isEven ? Colors.green : Colors.yellow,
child: new Center(
child: new CircleAvatar(
backgroundColor: Colors.white,
child: new Text('$index'),
),
)),
staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index.isEven ? 2 : 1),
)
4.效果图
分析:
最主要起到瀑布流效果的是这句代码: `staggeredTileBuilder: (int index) =>
new StaggeredTile.count(2, index.isEven ? 2 : 1),`
实际运用中需要根据实际情况对瀑布流item的高度进行调整。
- 论循证新闻的方法与意义——一种媒体融合背景下新闻生产方式创新
- 域名资讯:域名jiuhuang.com已搭建成“韭黄答题助手”网站
- Servlet开篇
- 浅谈中国域名的名与利
- 加密货币的火爆,tokens.com域名已50万美元成交
- 家具平台谷居完成2000万元融资,启用长尾双拼域名
- 如果未来的 AI 拥有意识,你舍得不理它吗?
- 微信这家人脸智慧时尚店可以“刷脸”试衣、付款
- 北京允许无人驾驶路测 难道是为方便圣诞老人送礼?
- 小程序新增多项功能,优化100多个功能点,堪称重磅!
- 人工智能的回报率:对冲基金嵌入机器学习?
- “人工智能助力上海科创中心建设”国际高峰论坛圆满结束
- 纳米白与Pandas
- 人工智能来了!实体零售会变成什么样?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- TextView显示文本控件两种方法 TextView显示link的方法
- Java入门005~Springboot2.2.4引入freemarker模板
- TabLayout使用方法详解
- Java入门006~springboot+freemarker+bootstrap快速实现管理后台
- Java入门007~springboot+freemarker+bootstrap快速实现分页功能
- ToolBar使用方法详解
- Android 中WallpaperManager用法实例
- Android实现屏幕各尺寸的获取的示例
- Android 中ContentProvider的实例详解
- Android Intent调用 Uri的方法总结
- Android 调用发送短信的方法
- Android 开发之Dialog中隐藏键盘的正确使用方法
- Android基于HttpUrlConnection类的文件下载实例代码
- Android ListView之setEmptyView正确使用方法
- 腾讯云Linux服务器安装Mysql8并实现远程访问