前言

GridView可以构建一个二维网格列表。需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。SliverGridDelegate是一个抽象类,定义了GridView Layout相关接口,子类需要通过实现它们来实现具体的布局算法。Flutter中提供了两个SliverGridDelegate的子类SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent。

接口描述

GridView({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required this.gridDelegate,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
List<Widget> children = const <Widget>[],
int semanticChildCount,
}) const SliverGridDelegateWithFixedCrossAxisCount({
@required this.crossAxisCount,
// 主轴方向的间距
this.mainAxisSpacing = 0.0,
// 横轴方向子元素的间距
this.crossAxisSpacing = 0.0,
// 子元素在横轴长度和主轴长度的比例
this.childAspectRatio = 1.0,
}) const SliverGridDelegateWithMaxCrossAxisExtent({
// 为子元素在横轴上的最大长度,之所以是“最大”长度,是因为横轴方向每个子元素的长度仍然是等分的
@required this.maxCrossAxisExtent,
this.mainAxisSpacing = 0.0,
this.crossAxisSpacing = 0.0,
// 所指的子元素横轴和主轴的长度比为最终的长度比
this.childAspectRatio = 1.0,
})

代码示例

// GridView

// GridView可以构建一个二维网格列表。需要关注的是gridDelegate参数,类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。
// SliverGridDelegate是一个抽象类,定义了GridView Layout相关接口,子类需要通过实现它们来实现具体的布局算法。
// Flutter中提供了两个SliverGridDelegate的子类SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent。 // SliverGridDelegateWithFixedCrossAxisCount
import 'package:flutter/material.dart'; class GridViewTest1 extends StatelessWidget{
@override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('SliverGridDelegateWithFixedCrossAxisCount'),
),
body: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 横轴三个子widget
crossAxisCount: 3,
// 宽高比为1时,子widget
childAspectRatio: 1.0
),
children: <Widget>[
Icon(Icons.ac_unit),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.free_breakfast)
],
), // 等价于 // body: GridView.count(
// crossAxisCount: 3,
// childAspectRatio: 1.0,
// children: <Widget>[
// Icon(Icons.ac_unit),
// Icon(Icons.airport_shuttle),
// Icon(Icons.all_inclusive),
// Icon(Icons.beach_access),
// Icon(Icons.cake),
// Icon(Icons.free_breakfast),
// ],
// ) );
}
} // SliverGridDelegateWithMaxCrossAxisExtent
class GridViewTest2 extends StatelessWidget{
@override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('SliverGridDelegateWithMaxCrossAxisExtent'),
),
body: GridView(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
// 元素在横轴上的最大长度
maxCrossAxisExtent: 120.0,
// 元素在横轴和主轴的长度比为最终的长度比
childAspectRatio: 2.0,
),
children: <Widget>[
Icon(Icons.ac_unit),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.free_breakfast)
],
), // 等价于 // body: GridView.extent(
// maxCrossAxisExtent: 120.0,
// childAspectRatio: 2.0,
// children: <Widget>[
// Icon(Icons.ac_unit),
// Icon(Icons.airport_shuttle),
// Icon(Icons.all_inclusive),
// Icon(Icons.beach_access),
// Icon(Icons.cake),
// Icon(Icons.free_breakfast)
// ],
// ), );
}
} // GridView.builder
// GridView都需要一个widget数组作为其子元素,这些方式都会提前将所有子widget都构建好,所以只适用于子widget数量比较少时,当子widget比较多时,我们可以通过GridView.builder来动态创建子widget
// 从一个异步数据源(如网络)分批获取一些Icon
class InfiniteGridView extends StatefulWidget{
@override
_InfiniteGridViewState createState() => _InfiniteGridViewState();
} class _InfiniteGridViewState extends State<InfiniteGridView>{
// 保存Icon数据
List<IconData> _icons = []; @override
void initState(){
// 初始化数据
_retrieveIcons();
} @override
Widget build(BuildContext context){ return Scaffold(
appBar: AppBar(
title: Text(''),
),
body: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// 每列三行
crossAxisCount: 3,
// 显示区域宽高相等
childAspectRatio: 1.0,
),
itemCount: _icons.length,
itemBuilder: (context, index){
// 如果显示到最后一个并且Icon总数小于200时继续获取数据
if (index == _icons.length - 1 && _icons.length < 200){
_retrieveIcons();
}
return Icon(_icons[index]);
}
),
);
} // 模拟异步获取数据
void _retrieveIcons(){
Future.delayed(Duration(milliseconds: 200)).then((e){
setState(() {
_icons.addAll([
Icons.ac_unit,
Icons.airport_shuttle,
Icons.all_inclusive,
Icons.beach_access,
Icons.free_breakfast,
]);
});
});
} }

总结

在实际开发中,可能会遇到子元素大小不等的情况,Pub上有一个包“flutter_staggered_grid_view” ,它实现了一个交错GridView的布局模型,可以很轻松的实现这种布局。

【Flutter】可滚动组件之GridView的更多相关文章

  1. 【Flutter学习】可滚动组件之ScrollView

    一,概述 ScrollView 是一个带有滚动的视图组件. 二,组成部分 ScrollView 由三部分组成: Scrollable - 它监听各种用户手势并实现滚动的交互设计.可滚动Widget都直 ...

  2. 【Flutter】可滚动组件之CustomScrollView

    前言 CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件.它可以包含多种滚动模型,举个例子,假设有一个页面,顶部需要一个GridView,底部需要一个ListView ...

  3. 【Flutter】可滚动组件简介

    前言 当组件内容超过当前显示视口(ViewPort)时,如果没有特殊处理,Flutter则会提示Overflow错误.为此,Flutter提供了多种可滚动组件(Scrollable Widget)用于 ...

  4. 【Flutter】可滚动组件之滚动控制和监听

    前言 可以用ScrollController来控制可滚动组件的滚动位置. 接口描述 ScrollController({ // 初始滚动位置 double initialScrollOffset = ...

  5. 【Flutter】可滚动组件之ListView

    前言 它可以沿一个方向线性排布所有子组件,并且它也可以支持基于Sliver的延迟构建模型. 接口描述 ListView({ Key key, // 可滚动widget公共参数 Axis scrollD ...

  6. 【Flutter】可滚动组件之SingleChildScrollView

    前言 SingleChildScrollView类似于Android中的ScrollView,它只能接收一个子组件. 接口描述 const SingleChildScrollView({ Key ke ...

  7. 第30讲 UI组件之 GridView组件

    第30讲 UI组件之 GridView组件 1.网格布局组件GridView GridView是一个ViewGroup(布局控件),可使用表格的方式显示组件,可滚动的控件.一般用于显示多张图片,比如实 ...

  8. Flutter中用ListView嵌套GridView报错异常

    flutter中的ListView组件和GridView组件都是常用的布局组件,有时候ListView中需要嵌套GridView来使用,例如下图: 这种情况就需要在ListView里面再嵌套一个Gri ...

  9. flutter系列之:flutter中常用的GridView layout详解

    目录 简介 GridView详解 GridView的构造函数 GridView的使用 总结 简介 GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridVie ...

随机推荐

  1. 题解-FJOI2018 领导集团问题

    题面 FJOI2018 领导集团问题 给一棵树 \(T(|T|=n)\),每个点有个权值 \(w_i\),从中选出一个子点集 \(P=\{x\in {\rm node}|x\in T\}\),使得 \ ...

  2. P4085 [USACO17DEC]Haybale Feast

    我又开始水了,感觉又是一道虚假的蓝题 题意 非常好理解,自己看吧 题解 可以比较轻易的发现,如果对于一段满足和大于等于 \(m\) 的区间和其满足和大于等于 \(m\) 的子区间来说,选择子区间肯定是 ...

  3. 通过git-bash 批量管理VMware虚拟机

    #先将vmrun .exe 加入环境变量 # 我这里是: ;C:\Program Files (x86)\VMware\VMware VIX; #cd E:/期中架构/#sh new\ 3.bash ...

  4. 使用OpenSSL自建一个HTTPS服务

    1. 理论知识 1.1 什么是https 传统的 HTTP 协议以明文方式进行通信,不提供任何方式的数据加密,很容易被中间攻击者破解通信内容或者伪装成服务器与客户端通信,在安全性上存在很大问题. HT ...

  5. 用 Roslyn 做个 JIT 的 AOP

    0. 前言 上接:AOP有几种实现方式 接下来说说怎么做AOP的demo,先用csharp 说下动态编织和静态编织,有时间再说点java的对应内容. 第一篇先说Roslyn 怎么做个JIT的AOP d ...

  6. 微信小程序api拦截器

    微信小程序api拦截器 完美兼容原生小程序项目 完美兼用小程序api的原本调用方式,无痛迁移 小程序api全Promise化 和axios一样的请求方式 小程序api自定义拦截调用参数和返回结果 强大 ...

  7. MetaException(message:Could not connect to meta store using any of the URIs provided. Most recent failure: org.apache.thrift.transport.TTransportException: java.net.ConnectException: 拒绝连接 (Connection

    hive在hive-site.xml中配置hive.metastore.uris属性,后启动异常 hive异常 [fan@master hive-0.13.1-cdh5.3.6]$ bin/hive ...

  8. 多任务-python实现-进程,协程,线程总结(2.1.16)

    @ 目录 1.类比 2.总结 关于作者 1.类比 一个生产玩具的工厂: 一个生产线成为一个进程,一个生产线有多个工人,所以工人为线程 单进程-多线程:一条生产线,多个工人 多进程-多线程:多条生产线, ...

  9. Atlas 2.1.0 实践(1)—— 编译Atlas

    为什么要做数据治理? 业务繁多,数据繁多,业务数据不断迭代.人员流动,文档不全,逻辑不清楚,对于数据很难直观理解,后期很难维护. 在大数据研发中,原始数据就有着非常多的数据库,数据表. 而经过数据的聚 ...

  10. Linux课程知识点总结(一)

    Linux课程知识点总结(一) 一.Linux系统的简介 1.1 什么是Linux Linux是一个免费的多用户.多任务的操作系统,其运行方式.功能和Unix系统很相似,但Linux系统的稳定性.安全 ...