GridView可以构建一个二维网格列表
属性
gridDelegate
类型是SliverGridDelegate,它的作用是控制GridView子组件如何排列(layout)。
SliverGridDelegate是一个抽象类,定义了GridView Layout相关接口,子类需要通过实现它们来实现具体的布局算法。Flutter中提供了两个SliverGridDelegate的子类SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent。
SliverGridDelegateWithFixedCrossAxisCount
该子类实现了一个横轴为固定数量子元素的layout算法。
crossAxisCount:横轴子元素的数量。此属性值确定后子元素在横轴的长度就确定了
mainAxisSpacing:主轴方向的间距。
crossAxisSpacing:横轴方向子元素的间距。
childAspectRatio:子元素在横轴长度和主轴长度的比例。由于crossAxisCount指定后,
子元素横轴长度就确定了,然后通过此参数值就可以确定子元素在主轴的长度。
因此子元素的大小是通过crossAxisCount和childAspectRatio两个参数共同决定的。
GridView.count
GridView.count构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以快速的创建横轴固定数量子元素的GridView。
Widget gridView = GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,//横轴4个子widget
childAspectRatio: 1,//宽高比为1:1
),
children: <Widget>[
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
],
);
Widget gridViewTwo = GridView.count(
crossAxisCount: 4,//横轴4个子widget
childAspectRatio: 1,//宽高比为1:1
children: <Widget>[
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
],
);
2个效果一样
SliverGridDelegateWithMaxCrossAxisExtent
该子类实现了一个横轴子元素为固定最大长度的layout算法。
maxCrossAxisExtent为子元素在横轴上的最大长度,之所以是“最大”长度,是因为横轴方向每个子元素的长度仍然是等分的
GridView.extent
GridView.extent构造函数内部使用了SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以快速的创建纵轴子元素为固定最大长度的的GridView
Widget gridViewThree = GridView(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 150,//
childAspectRatio: 2,//宽高比为2:1
),
children: <Widget>[
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
],
);
Widget gridViewFour = GridView.extent(
maxCrossAxisExtent: 150,//
childAspectRatio: 2,//宽高比为2:1
children: <Widget>[
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
Icon(Icons.tab),
],
);
这两效果一样
GridView.builder
当子widget比较多时,我们可以通过GridView.builder来动态创建子widget。itemBuilder为子widget构建器。
class InfiniteGridView extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return InfiniteGridViewState();
}
}
class InfiniteGridViewState extends State<InfiniteGridView>{
List<IconData> icons = [];
@override
void initState() {
super.initState();
//创建数据
getIcons();
}
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
),
itemCount: icons.length,
itemBuilder: (context,index){
if(index == icons.length -1 && icons.length < 200){
//小于200个 继续添加数据
getIcons();
}
return Icon(icons[index]);
}
);
}
void getIcons() {
Future.delayed(Duration(milliseconds: 500)).then((value) {
setState(() {
icons.addAll([
Icons.map,
Icons.add,
Icons.radio,
Icons.battery_charging_full,
Icons.add_a_photo,
Icons.g_translate,
Icons.access_time,
Icons.account_circle,
Icons.ac_unit,
]);
});
});
}
}
getIcons()方法中我们通过Future.delayed来模拟从异步数据源获取数据,每次获取数据需要200毫秒,获取成功后将新数据添加到_icons,然后调用setState重新构建。