一、介绍
GridView矩阵式列表(网格布局)
当数据量很大的时候用矩阵方式排列比较清晰。此时我们可以用网格列表组件 GridView 实现布局。
GridView 创建网格列表有多种方式,下面我们主要介绍两种。
1、可以通过 GridView.count 实现网格布局
2、通过 GridView.builder 实现网格布局
二、GridView.count源码
GridView.count({
Key key,
Axis scrollDirection = Axis.vertical,//滚动方向
bool reverse = false,//组件反向排序
ScrollController controller,//滚动监听
bool primary,//值为false,内容不足不可滑动,值为true,内容不足可以尝试滑动
ScrollPhysics physics,//滑动类型设置
bool shrinkWrap = false,//内容适配
EdgeInsetsGeometry padding,//内边距
@required int crossAxisCount,//列数
double mainAxisSpacing = 0.0,//主轴的间距
double crossAxisSpacing = 0.0,//横轴的间距
double childAspectRatio = 1.0,//
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,//设置预加载区域
List<Widget> children = const <Widget>[],//子组件
int semanticChildCount,//提供语义信息的子组件数量
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
),
childrenDelegate = SliverChildListDelegate(
children,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent,
semanticChildCount: semanticChildCount ?? children.length,
dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId,
clipBehavior: clipBehavior,
);
三、GridView.count参数介绍
属性 | 说明 |
---|---|
scrollDirection | 滚动方向 Axis.vertical竖向滚动 Axis.horizontal横向滚动 |
reverse | 组件反向排序 |
controller | 滚动监听 |
primary | 值为false,内容不足不可滑动,值为true,内容不足可以尝试滑动 |
shrinkWrap | 内容适配,默认为false |
padding | 内边距 |
crossAxisCount | 列数 |
mainAxisSpacing | 主轴之间的间距 |
crossAxisSpacing | 横轴之间的间距 |
childAspectRatio | 设置宽高的比例 GridView的子组件直接设置宽高没有反应,可以通过childAspectRatio修改宽高 |
cacheExtent | 设置预加载区域 |
children | 组件元素 const <Widget>[] 数组内添加widget类型的数据 flutter的所有组件都是widget,也就是说所有的GridView可以添加所有的组件 |
semanticChildCount | 提供语义信息的子组件数量 |
四、GridView.count的demo
1、简单实现
return GridView.count(
scrollDirection: Axis.vertical,
crossAxisCount: 3,
children: [
Text("我是文本1"),
Text("我是文本2"),
Text("我是文本3"),
Text("我是文本4"),
Text("我是文本5"),
Text("我是文本6"),
Text("我是文本7"),
Text("我是文本8"),
Text("我是文本9"),
],
);
2、图文列表
void main() {
runApp(new GridStu());
}
class GridStu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("gridView学习"),
),
body: new Stu(),
),
);
}
}
class Stu extends StatelessWidget {
List listData = [
{
"title": "标题1",
"author": "内容1",
"image": "https://www.itying.com/images/flutter/1.png"
},
{
"title": "标题2",
"author": "内容2",
"image": "https://www.itying.com/images/flutter/2.png"
},
{
"title": "标题3",
"author": "内容3",
"image": "https://www.itying.com/images/flutter/3.png"
},
{
"title": "标题4",
"author": "内容4",
"image": "https://www.itying.com/images/flutter/4.png"
},
{
"title": "标题5",
"author": "内容5",
"image": "https://www.itying.com/images/flutter/5.png"
},
{
"title": "标题6",
"author": "内容6",
"image": "https://www.itying.com/images/flutter/6.png"
},
{
"title": "标题7",
"author": "内容7",
"image": "https://www.itying.com/images/flutter/7.png"
},
{
"title": "标题8",
"author": "内容8",
"image": "https://www.itying.com/images/flutter/1.png"
},
{
"title": "标题9",
"author": "内容9",
"image": "https://www.itying.com/images/flutter/2.png"
}
];
List<Widget> _getData() {
List<Widget> list = new List();
for (var i = 0; i < listData.length; i++) {
list.add(Container(
child: ListView(
children: [
Image.network(
listData[i]["image"],
fit: BoxFit.cover,
),
Text(
listData[i]["title"],
textAlign:TextAlign.center,
)
],
),
//
decoration:
BoxDecoration(border: Border.all(color: Colors.black26, width: 1)),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return GridView.count(
//设置滚动方向
scrollDirection: Axis.vertical,
//设置列数
crossAxisCount: 3,
//设置内边距
padding: EdgeInsets.all(10),
//设置横向间距
crossAxisSpacing: 10,
//设置主轴间距
mainAxisSpacing: 10,
children: _getData(),
);
}
}
五、GridView.build()源码
GridView.builder({
Key key,
Axis scrollDirection = Axis.vertical,
bool reverse = false,
ScrollController controller,
bool primary,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
@required this.gridDelegate,
@required IndexedWidgetBuilder itemBuilder,
int itemCount,
bool addAutomaticKeepAlives = true,
bool addRepaintBoundaries = true,
bool addSemanticIndexes = true,
double cacheExtent,
int semanticChildCount,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual,
String restorationId,
Clip clipBehavior = Clip.hardEdge,
}) : assert(gridDelegate != null),
childrenDelegate = SliverChildBuilderDelegate(
itemBuilder,
childCount: itemCount,
addAutomaticKeepAlives: addAutomaticKeepAlives,
addRepaintBoundaries: addRepaintBoundaries,
addSemanticIndexes: addSemanticIndexes,
),
super(
key: key,
scrollDirection: scrollDirection,
reverse: reverse,
controller: controller,
primary: primary,
physics: physics,
shrinkWrap: shrinkWrap,
padding: padding,
cacheExtent: cacheExtent,
semanticChildCount: semanticChildCount ?? itemCount,
dragStartBehavior: dragStartBehavior,
keyboardDismissBehavior: keyboardDismissBehavior,
restorationId: restorationId,
clipBehavior: clipBehavior,
);
六、GridView.builder参数介绍
GridView.builder的参数几乎一样,但是必须配置itemCount和itemBuilder
属性 | 说明 |
---|---|
itemCount | 子组件的数量 |
itemBuilder | 子组件的构造itemBuilder:(context,index){} |
gridDelegate | 构造 GridView 的委托者 SliverGridDelegateWithFixedCrossAxisCount(),可以设置列数 SliverGridDelegateWithMaxCrossAxisExtent(),根据设置的宽高比,自动算出列数 |
七、GridView.builder的demo
class Stu extends StatelessWidget {
List listData = [
{
"title": "标题1",
"author": "内容1",
"image": "https://www.itying.com/images/flutter/1.png"
},
{
"title": "标题2",
"author": "内容2",
"image": "https://www.itying.com/images/flutter/2.png"
},
{
"title": "标题3",
"author": "内容3",
"image": "https://www.itying.com/images/flutter/3.png"
},
{
"title": "标题4",
"author": "内容4",
"image": "https://www.itying.com/images/flutter/4.png"
},
{
"title": "标题5",
"author": "内容5",
"image": "https://www.itying.com/images/flutter/5.png"
},
{
"title": "标题6",
"author": "内容6",
"image": "https://www.itying.com/images/flutter/6.png"
},
{
"title": "标题7",
"author": "内容7",
"image": "https://www.itying.com/images/flutter/7.png"
},
{
"title": "标题8",
"author": "内容8",
"image": "https://www.itying.com/images/flutter/1.png"
},
{
"title": "标题9",
"author": "内容9",
"image": "https://www.itying.com/images/flutter/2.png"
}
];
@override
Widget build(BuildContext context) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
//设置列数
crossAxisCount: 3,
//设置横向间距
crossAxisSpacing: 10,
//设置主轴间距
mainAxisSpacing: 10,
),
scrollDirection: Axis.vertical,
itemCount: listData.length,
itemBuilder:(context,index){
return Container(
child: ListView(
children: [
Image.network(
listData[index]["image"],
fit: BoxFit.cover,
),
Text(
listData[index]["title"],
textAlign:TextAlign.center,
)
],
),
decoration:
BoxDecoration(border: Border.all(color: Colors.black26, width: 1)),
);
},
);
}
}