Flutter基础组件(4)-GridView
1. GridView的介绍
学习过ListView的使用,我们接下来学习GridView(网格布局)的使用,GridView有5种构造函数:GridView,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>[],
})
这里很多的属性都是和ListView相似的,除了一个在GridView.builder必要的参数gridDelegate,就让我们来重点关注下
gridDelegate
这个参数,它其实是GridView
组件如何控制排列子元素的一个委托。跟踪源码我们可以在scroll_view.dart中看到,gridDelegate
的类型是SliverGridDelegate
,进一步跟踪进sliver_grid.dart可以看到SliverGridDelegate
其实是一个抽象类,而且一共有两个实现类:
SliverGridDelegateWithFixedCrossAxisCount:用于固定列数的场景;
SliverGridDelegateWithMaxCrossAxisExtent:用于子元素有最大宽度限制的场景;
2. GridView的使用
想要使用GridView我们就要首先构造数据:
List<String> getDataList() {
List<String> list = [];
for (int i = 0; i < 100; i++) {
list.add(i.toString());
}
return list;
}
List<Widget> getWidgetList() {
return getDataList().map((item) => getItemContainer(item)).toList();
}
Widget getItemContainer(String item) {
return Container(
alignment: Alignment.center,
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: Colors.cyan,
);
}
2.1 GridView.count
GridView.count(
//水平子Widget之间间距
crossAxisSpacing: 10.0,
//垂直子Widget之间间距
mainAxisSpacing: 30.0,
//GridView内边距
padding: EdgeInsets.all(10.0),
//一行的Widget数量
crossAxisCount: 2,
//子Widget宽高比例
childAspectRatio: 2.0,
//子Widget列表
children: getWidgetList(),
);
对于这种写法,此时单个Widget的宽高已经不起作用了。
在我上面构造数据的那一步中,我并没有指定Container的的宽高,这里我们就将其宽高设置为5。
Widget getItemContainer(String item) {
return Container(
width: 5.0,
height: 5.0,
alignment: Alignment.center,
child: Text(
item,
style: TextStyle(color: Colors.white, fontSize: 20),
),
color: Colors.blue,
);
}
可以看出没有效果。因为,我们在这里已经指定了每一行分成几列以及宽高比,还有边距等等。所以,我们后面再指定单个item的宽高,已经无效。
2.2 GridView.builder(SliverGridDelegateWithFixedCrossAxisCount)
Widget build(BuildContext context) {
List<String> datas = getDataList();
return GridView.builder(
itemCount: datas.length,
//SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//横轴元素个数
crossAxisCount: 3,
//纵轴间距
mainAxisSpacing: 20.0,
//横轴间距
crossAxisSpacing: 10.0,
//子组件宽高长度比例
childAspectRatio: 1.0),
itemBuilder: (BuildContext context, int index) {
//Widget Function(BuildContext context, int index)
return getItemContainer(datas[index]);
});
}
2.3 GridView.builder(SliverGridDelegateWithMaxCrossAxisExtent)
GridView.builder(
itemCount: datas.length,
itemBuilder: (BuildContext context, int index) {
return getItemContainer(datas[index]);
},
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
//单个子Widget的水平最大宽度
maxCrossAxisExtent: 200,
//水平单个子Widget之间间距
mainAxisSpacing: 20.0,
//垂直单个子Widget之间间距
crossAxisSpacing: 10.0
),
);
对于SliverGridDelegateWithMaxCrossAxisExtent而言,水平方向元素个数不再固定,其水平个数也就是有几列,由maxCrossAxisExtent和屏幕的宽度以及padding和mainAxisSpacing等决定。
2.4 GridView.custom
Widget build(BuildContext context) {
List<String> datas = getDataList();
return GridView.custom(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 10.0, crossAxisSpacing: 20.0, ),
childrenDelegate: SliverChildBuilderDelegate((context, position) {
return getItemContainer(datas[position]);
}, childCount: datas.length));
}
想了解更多Flutter学习知识请联系:QQ(814299221)