【Flutter】可滚动组件之GridView
前言
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的更多相关文章
- 【Flutter学习】可滚动组件之ScrollView
一,概述 ScrollView 是一个带有滚动的视图组件. 二,组成部分 ScrollView 由三部分组成: Scrollable - 它监听各种用户手势并实现滚动的交互设计.可滚动Widget都直 ...
- 【Flutter】可滚动组件之CustomScrollView
前言 CustomScrollView是可以使用Sliver来自定义滚动模型(效果)的组件.它可以包含多种滚动模型,举个例子,假设有一个页面,顶部需要一个GridView,底部需要一个ListView ...
- 【Flutter】可滚动组件简介
前言 当组件内容超过当前显示视口(ViewPort)时,如果没有特殊处理,Flutter则会提示Overflow错误.为此,Flutter提供了多种可滚动组件(Scrollable Widget)用于 ...
- 【Flutter】可滚动组件之滚动控制和监听
前言 可以用ScrollController来控制可滚动组件的滚动位置. 接口描述 ScrollController({ // 初始滚动位置 double initialScrollOffset = ...
- 【Flutter】可滚动组件之ListView
前言 它可以沿一个方向线性排布所有子组件,并且它也可以支持基于Sliver的延迟构建模型. 接口描述 ListView({ Key key, // 可滚动widget公共参数 Axis scrollD ...
- 【Flutter】可滚动组件之SingleChildScrollView
前言 SingleChildScrollView类似于Android中的ScrollView,它只能接收一个子组件. 接口描述 const SingleChildScrollView({ Key ke ...
- 第30讲 UI组件之 GridView组件
第30讲 UI组件之 GridView组件 1.网格布局组件GridView GridView是一个ViewGroup(布局控件),可使用表格的方式显示组件,可滚动的控件.一般用于显示多张图片,比如实 ...
- Flutter中用ListView嵌套GridView报错异常
flutter中的ListView组件和GridView组件都是常用的布局组件,有时候ListView中需要嵌套GridView来使用,例如下图: 这种情况就需要在ListView里面再嵌套一个Gri ...
- flutter系列之:flutter中常用的GridView layout详解
目录 简介 GridView详解 GridView的构造函数 GridView的使用 总结 简介 GridView是一个网格化的布局,如果在填充的过程中子组件超出了展示的范围的时候,那么GridVie ...
随机推荐
- Panda交易所获悉,五地股权市场获批参与「区块链建设试点」
Panda交易所获悉,北京市地方金融监督管理局官网于7月21日发布信息显示,"证监会发布<关于原则同意北京.上海.江苏.浙江.深圳等5家区域性股权市场开展区块链建设工作的函>,原 ...
- hashmap底层:jdk1.8前后的改变
将hashmap和currenthashmap放一块进行比较,是因为二者的结构相差不多,只不过后者是线程安全的. 首先说hashmap,在jdk1.8之前,hashmap的存储结构是数组+链表的形式, ...
- Hadoop使用实例 词频统计和气象分析
一.词频统计 下载喜欢的电子书或大量文本数据,并保存在本地文本文件中 编写map与reduce函数 本地测试map与reduce 将文本数据上传至HDFS上 用hadoop streaming提交任务 ...
- MySQL PXC集群安装配置
1.关闭防火墙 [root@node04 ~]#systemctl disable firewalld [root@node04 ~]#systemctl stop firewalld [root@n ...
- Greenplum 性能优化之路 --(一)分区表
一.什么是分区表 分区表就是将一个大表在物理上分割成若干小表,并且整个过程对用户是透明的,也就是用户的所有操作仍然是作用在大表上,不需要关心数据实际上落在哪张小表里面.Greenplum 中分区表的原 ...
- 谁再问Servlet的问题,我就亲自上门来教学了
1. 概述 在这篇简短的文章中,我们将从概念上理解什么是servlet 和 servlet 容器以及它们是如何工作的. 同时,还能在请求.响应.会话对象.共享变量和多线程的上下文中看到它们的身影. 2 ...
- spark踩坑--WARN ProcfsMetricsGetter: Exception when trying to compute pagesize的最全解法
spark踩坑--WARN ProcfsMetricsGetter: Exception when trying to compute pagesize的最全解法 问题描述 大概是今年上半年的时候装了 ...
- iOS 14 YYAnimatedImageView加载图片失败处理
1.问题出在YYAnimatedImageView源码一个方法中 - (void)displayLayer:(CALayer *)layer { if (_curFrame) { layer.cont ...
- HCIP -- OSPF 总结
OSPF:Open Shortest path First :开方式最短路径优先 一.基础知识: 1.使用范围:IGP 2.协议算法特点:链路状态型路由协议,SPF算法 3.协议是否传递网络掩码:是 ...
- C#访问Access数据库提示未安装ISAM
解决办法 1.在前面加上Jet OLEDB:,如: Jet OLEDB:Database Password='zt' <add name="ConStrOleDb" conn ...