【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 ...
随机推荐
- sql语句执行次序
from→on→join→where→group by→having→select→distinct→order by→limit
- 代理ip知识
一.没有使用代理服务器的情况: REMOTE_ADDR = 您的 IP HTTP_VIA = 没数值或不显示 HTTP_X_FORWARDED_FOR = 没数值或不显示 二.使用 ...
- gnuplot图例legend设置
//将图例放在右下角 set key bottom //将图例放在中间 set key center //将图例放在左边 set key left //将图例放在指定位置右下角的坐标为(10,0.7) ...
- 【JAVA基础】static的定义
public class STATIC { public static void main(String[] args) { // 创建两个不同的类 只要赋值一个 另外一个定义好的static属性 会 ...
- Python之word文档模板套用 - 真正的模板格式套用
Python之word文档模板套用: 1 ''' 2 #word模板套用2:套用模板 3 ''' 4 5 #导入所需库 6 from docx import Document 7 ''' 8 #另存w ...
- 浅析Python闭包
1.什么是闭包 在介绍闭包概念前,我们先来看一段简短的代码 def sum_calc(*args): def wrapper(): sum = 0 for n in args: sum += n; r ...
- Vue2+Koa2+Typescript前后端框架教程--04班级管理示例(路由调用控制器)
上篇文章分享了简单的三层模式和基础文件夹的创建,本篇将以示例的形式详细具体的展示Router.Controller.Service.Model之间业务处理和数据传输. 1. 班级管理数据模型创建.数据 ...
- @Transient 注解
使用 @Transient 表示该属性并非是一个要映射到数据库表中的字段,只是起辅助作用.ORM框架将会忽略该属性
- 安装git之后,桌面出现蓝色问号的解决方法
安装了git之后,桌面的图标全部变成蓝色的问号. 把隐藏的文件全部显示,也没有在桌面找到.git的文件, 解决步骤: 1.把隐藏的文件全部显示: 工具-文件夹选项-查看在"隐藏文件和文件夹& ...
- Atlas 2.1.0 实践(2)—— 安装Atlas
在完成Atlas编译以后,就可以进行Atlas的安装了.Atlas的安装主要是安装Atlas的Server端,也就Atlas的管理页面,并确保Atlas与Kafka Hbase Solr等组件的集成. ...