Open SmallStoneSK opened 5 years ago
Flutter作为时下最流行的技术之一,凭借其出色的性能以及抹平多端的差异优势,早已引起大批技术爱好者的关注,甚至一些闲鱼,美团,腾讯等大公司均已投入生产使用。虽然目前其生态还没有完全成熟,但身靠背后的Google加持,其发展速度已经足够惊人,可以预见将来对Flutter开发人员的需求也会随之增长。
Flutter
闲鱼
美团
腾讯
Google
无论是为了现在的技术尝鲜还是将来的潮流趋势,都9102年了,作为一个前端开发者,似乎没有理由不去尝试它。正是带着这样的心理,笔者也开始学习Flutter,同时建了一个用于练习的仓库,后续所有代码都会托管在上面,欢迎star,一起学习。
经过上一篇对ListView组件的学习,我们已经对滚动型组件的使用有了初步认识,这对今天要学习的GridView组件十分有帮助。因为两者都继承自BoxScrollView,所以两者的属性有80%以上是相同的,用法非常相似。
ListView
GridView
BoxScrollView
而且如下图所示可见,GridView网格布局在app中的使用频率其实非常高,所以接下来就让我们来看看在Flutter中如何使用吧~
今天我们的主角GridView一共有5个构造函数:GridView,GridView.builder,GridView.count,GridView.extent和GridView.custom。但是不用慌,因为可以说其实掌握其默认构造函数就都会了~
GridView.builder
GridView.count
GridView.extent
GridView.custom
来看下GridView构造函数(已省略不常用属性):
GridView({ Key key, Axis scrollDirection = Axis.vertical, bool reverse = false, ScrollController controller, ScrollPhysics physics, bool shrinkWrap = false, EdgeInsetsGeometry padding, @required this.gridDelegate, double cacheExtent, List<Widget> children = const <Widget>[], })
虽然又是一大堆属性,但是大部分都很熟悉,老朋友嘛~除了一个必填参数gridDelegate外,全和ListView默认构造函数的参数一样,这也是文章开头为什么说掌握了ListView再学GridView非常容易的原因。
gridDelegate
那么接下来,就让我们来重点关注下gridDelegate这个参数,它其实是GridView组件如何控制排列子元素的一个委托。跟踪源码我们可以在scroll_view.dart中看到,gridDelegate的类型是SliverGridDelegate,进一步跟踪进sliver_grid.dart可以看到SliverGridDelegate其实是一个抽象类,而且一共有两个实现类:
SliverGridDelegate
SliverGridDelegateWithFixedCrossAxisCount
SliverGridDelegateWithMaxCrossAxisExtent
我们先来看下SliverGridDelegateWithFixedCrossAxisCount,根据类名我们也能大概猜它是干什么用的:如果你的布局中每一行的列数是固定的,那你就应该用它。
每一行的列数是固定的
来看下其构造函数:
SliverGridDelegateWithFixedCrossAxisCount({ @required this.crossAxisCount, this.mainAxisSpacing = 0.0, this.crossAxisSpacing = 0.0, this.childAspectRatio = 1.0, })
crossAxisCount
mainAxisSpacing
crossAxisSpacing
childAspectRatio
想必看到上面的示例图,你就秒懂其中各个参数的含义了。不过,这里有一点需要特别注意:如果你的子元素宽高比例不为1,那么你一定要设置childAspectRatio属性。
SliverGridDelegateWithMaxCrossAxisExtent在实际应用中可能会比较少,来看下其构造函数:
SliverGridDelegateWithMaxCrossAxisExtent({ @required this.maxCrossAxisExtent, this.mainAxisSpacing = 0.0, this.crossAxisSpacing = 0.0, this.childAspectRatio = 1.0, })
可以看到除了maxCrossAxisExtent外,其他参数和SliverGridDelegateWithFixedCrossAxisCount都是一样的。那么maxCrossAxisExtent是干什么的呢?我们来看个例子:
maxCrossAxisExtent
假如手机屏宽375,crossAxisSpacing值为0,
375
0
125
3
125 * 3 = 375
375/3
126
126 * 3 > 375
124
4
124 * 3 < 375
375/4
可以看到,maxCrossAxisExtent其实就是告诉GridView组件子元素的最大宽度可能是多少,然后计算得到合适的列宽(实际上,我们也很少这么应用,所以这种方法的使用频率不高)。
经过前面的介绍,我们已经对GrdiView组件有了初步了解,下面就来看看如何使用。还记得之前GridView的各种构造函数吗?其实:
GrdiView
children
ListView.builder
先来看一个简单的例子,它使用到GridView.count构造函数模仿美团外卖首页服务列表(服务菜单项的代码可以看这里,也算是对基础组件使用的进一步巩固):
代码(文件地址)
GridView.count( crossAxisCount: 5, padding: EdgeInsets.symmetric(vertical: 0), children: serviceList.map((item) => ServiceItem(data: item)).toList(), ) /*************/ /* 完全等同于 */ /************/ GridView( padding: EdgeInsets.symmetric(vertical: 0), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 5, ), children: serviceList.map((item) => ServiceItem(data: item)).toList(), )
预览
再来看一个模仿喜马拉雅中相声列表用到GridView.builder创建网格布局的具体例子(相声卡片的代码可以看这里):
GridView.builder( shrinkWrap: true, itemCount: programmeList.length, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.symmetric(horizontal: 16), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, mainAxisSpacing: 10, crossAxisSpacing: 10, childAspectRatio: 0.7, ), itemBuilder: (context, index) { return Programme(data: programmeList[index]); }, )
本文先是介绍了GridView组件的属性含义,并着重讲解了SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent分别适用的应用场景。然后,通过两个实际的应用例子介绍了GridView组件常用的构造函数使用方法。希望通过本文的介绍,你可以掌握Flutter中网格型布局的使用~
本文所有代码托管在这儿,欢迎一起交流学习~
1. 前言
Flutter
作为时下最流行的技术之一,凭借其出色的性能以及抹平多端的差异优势,早已引起大批技术爱好者的关注,甚至一些闲鱼
,美团
,腾讯
等大公司均已投入生产使用。虽然目前其生态还没有完全成熟,但身靠背后的Google
加持,其发展速度已经足够惊人,可以预见将来对Flutter
开发人员的需求也会随之增长。无论是为了现在的技术尝鲜还是将来的潮流趋势,都9102年了,作为一个前端开发者,似乎没有理由不去尝试它。正是带着这样的心理,笔者也开始学习
Flutter
,同时建了一个用于练习的仓库,后续所有代码都会托管在上面,欢迎star,一起学习。经过上一篇对
ListView
组件的学习,我们已经对滚动型组件的使用有了初步认识,这对今天要学习的GridView
组件十分有帮助。因为两者都继承自BoxScrollView
,所以两者的属性有80%以上是相同的,用法非常相似。而且如下图所示可见,
GridView
网格布局在app中的使用频率其实非常高,所以接下来就让我们来看看在Flutter
中如何使用吧~2. 初识GridView
今天我们的主角
GridView
一共有5个构造函数:GridView
,GridView.builder
,GridView.count
,GridView.extent
和GridView.custom
。但是不用慌,因为可以说其实掌握其默认构造函数就都会了~来看下
GridView
构造函数(已省略不常用属性):虽然又是一大堆属性,但是大部分都很熟悉,老朋友嘛~除了一个必填参数
gridDelegate
外,全和ListView
默认构造函数的参数一样,这也是文章开头为什么说掌握了ListView
再学GridView
非常容易的原因。那么接下来,就让我们来重点关注下
gridDelegate
这个参数,它其实是GridView
组件如何控制排列子元素的一个委托。跟踪源码我们可以在scroll_view.dart中看到,gridDelegate
的类型是SliverGridDelegate
,进一步跟踪进sliver_grid.dart可以看到SliverGridDelegate
其实是一个抽象类,而且一共有两个实现类:SliverGridDelegateWithFixedCrossAxisCount
:用于固定列数的场景;SliverGridDelegateWithMaxCrossAxisExtent
:用于子元素有最大宽度限制的场景;2.1 SliverGridDelegateWithFixedCrossAxisCount
我们先来看下
SliverGridDelegateWithFixedCrossAxisCount
,根据类名我们也能大概猜它是干什么用的:如果你的布局中每一行的列数是固定的
,那你就应该用它。来看下其构造函数:
crossAxisCount
:列数,即一行有几个子元素;mainAxisSpacing
:主轴方向上的空隙间距;crossAxisSpacing
:次轴方向上的空隙间距;childAspectRatio
:子元素的宽高比例。想必看到上面的示例图,你就秒懂其中各个参数的含义了。不过,这里有一点需要特别注意:如果你的子元素宽高比例不为1,那么你一定要设置
childAspectRatio
属性。2.2 SliverGridDelegateWithMaxCrossAxisExtent
SliverGridDelegateWithMaxCrossAxisExtent
在实际应用中可能会比较少,来看下其构造函数:可以看到除了
maxCrossAxisExtent
外,其他参数和SliverGridDelegateWithFixedCrossAxisCount
都是一样的。那么maxCrossAxisExtent
是干什么的呢?我们来看个例子:假如手机屏宽
375
,crossAxisSpacing
值为0
,maxCrossAxisExtent
值为125
时,网格列数将是3
。因为125 * 3 = 375
,刚好,每一列的宽度就是375/3
。maxCrossAxisExtent
值为126
时,网格列数将是3
。因为126 * 3 > 375
,显示不下,每一列的宽度将是375/3
。maxCrossAxisExtent
值为124
时,网格列数将是4
。因为124 * 3 < 375
,仍有多余,每一列的宽度将是375/4
。可以看到,
maxCrossAxisExtent
其实就是告诉GridView
组件子元素的最大宽度可能是多少,然后计算得到合适的列宽(实际上,我们也很少这么应用,所以这种方法的使用频率不高)。3. 实际应用
经过前面的介绍,我们已经对
GrdiView
组件有了初步了解,下面就来看看如何使用。还记得之前GridView
的各种构造函数吗?其实:GridView
默认构造函数可以类比于ListView
默认构造函数,适用于有限个数子元素的场景,因为GridView
组件会一次性全部渲染children
中的子元素组件;GridView.builder
构造函数可以类比于ListView.builder
构造函数,适用于长列表的场景,因为GridView
组件会根据子元素是否出现在屏幕内而动态创建销毁,减少内存消耗,更高效渲染;GridView.count
构造函数是GrdiView
使用SliverGridDelegateWithFixedCrossAxisCount
的简写(语法糖),效果完全一致;GridView.extent
构造函数式GridView
使用SliverGridDelegateWithMaxCrossAxisExtent
的简写(语法糖),效果完全一致。先来看一个简单的例子,它使用到
GridView.count
构造函数模仿美团外卖首页服务列表(服务菜单项的代码可以看这里,也算是对基础组件使用的进一步巩固):代码(文件地址)
预览
再来看一个模仿喜马拉雅中相声列表用到
GridView.builder
创建网格布局的具体例子(相声卡片的代码可以看这里):代码(文件地址)
预览
4. 总结
本文先是介绍了
GridView
组件的属性含义,并着重讲解了SliverGridDelegateWithFixedCrossAxisCount
和SliverGridDelegateWithMaxCrossAxisExtent
分别适用的应用场景。然后,通过两个实际的应用例子介绍了GridView
组件常用的构造函数使用方法。希望通过本文的介绍,你可以掌握Flutter
中网格型布局的使用~本文所有代码托管在这儿,欢迎一起交流学习~