我们上篇博客Flutter踩坑之路(二)一Flutter初识(基本组件(一))讲了Container、Text、Image以及Icon的使用,我们这篇博客来讲一下Flutter中列表的使用。
列表布局是我们项目开发中最常用的一种布局方式。Flutter 中我们可以通过 ListView 来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。列表有以下 分类:
1.垂直的列表
2.水平列表
3.动态列表
4.矩阵式列表
基础列表组件
基础列表组件为ListView组件,其常用属性如下表所示:
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
scrollDirection | Axis | Axis.vertical | 列表的排列方向,Axis.horizontal 水平列表, Axis.vertical 垂直列表 |
padding | EdgeInsetsGeometry | 内边距 | |
reverse | bool | false | 组件排列反向 |
children | List<Widget> | 列表元素,List元素全部为Widget类型 |
下面我们来写一个基础列表的例子,来加深一下我们对基础列表的理解。示例代码如下:
ListView(
children: <Widget>[
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
ListTile(
//添加图标
leading: Icon(Icons.ac_unit),
//添加文字
title: Text("条目"),
),
],
),
效果图如下所示:
水平列表组件
水平列表组件即为水平方向排列的组件,列表内部元素以水平方向排列。把ListView组件的scrollDirection属性设置为Axis.horizontial即可。示例代码如下:
ListView(
scrollDirection: Axis.horizontal,
children: <Widget>[
Container(
width: 20.0,
color: Colors.green,
),
Container(
width: 50.0,
color: Colors.red,
),
Container(
width: 100.0,
color: Colors.blue,
child: Column(
children: <Widget>[
Text("水平列表1",style: TextStyle(
fontSize: 32.0,color: Colors.white,fontStyle: FontStyle.italic,
),
),
],
),
),
Container(
width: 200.0,
child: Column(
children: <Widget>[
Image.network("http://hbimg.b0.upaiyun.com/c4d437ba680607d1d20a855dba0fa322cebf6c0a1c941-eUGNCk_fw658",fit: BoxFit.cover,),
],
),
),
Container(
width: 160.0,
color: Colors.purple,
)
],
)
效果图如下所示:
长列表组件
当列表的数据项过多的话,我们需要用到长列表。长列表也是使用ListView作为基础组件的,只不过是需要添加一个列表构造器itemBuilder来实现。代码示例如下:
ListView.builder(
itemCount: items.length,
itemBuilder:_itemBuilder
),
List<String> items=new List();
LongListViewDemo({ Key key }) : super(key: key){
for(var i=0;i<100;i++){
items.add("列表$i");
}
}
Widget _itemBuilder(BuildContext context, int index) {
return Text(items[index],
style: TextStyle(
color: Colors.blue,
fontSize: 32.0,
),
);
}
示例效果如下:
ListView.separated
我们可以看到上面列表并没有进行分割,都是在一起的,我们可以使用ListView.separated,ListView.separated可以在生成的列表项之间添加一个分割组件,它比ListView.builder多了一个separatorBuilder参数,该参数是一个分割组件生成器。示例代码如下:
ListView.separated(
itemCount: items.length,
itemBuilder:_itemBuilder,
separatorBuilder: _separatorBuilder,
),
Widget _separatorBuilder(BuildContext context, int index) {
return Divider(
color: Colors.red,//添加分割线的颜色
);
}
效果图如下所示:
网格列表
网格列表组件,即GridView组件,可以实现多行多列的列表。使用GridView创建网格列表有很多种方式:
1.GridView.count通过单行展示个数创建GridView
2.GridView.extent通过最大宽度创建GridView
网格列表的属性如下表所示:
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
scrollDirection | Axis | Axis.vertial | 滚动方法,垂直和水平,默认是垂直 |
padding | EdgeInsetsGeometry | 内边距,四周的空白区域 | |
resolve | bool | false | 组件反向排序 |
crossAxisSpacing | double | 水平子 Widget 之间间距 | |
mainAxisSpacing | double | 垂直子 Widget 之间间距 | |
crossAxisCount | int | 1 | 一行的 Widget 数量 |
childAspectRatio | double | 子 Widget 宽高比例 | |
children | <Widget>[ ] | ||
gridDelegate | SliverGridDelegate | SliverGridDelegateWithFixedCrossAxisCount(常用) SliverGridDelegateWithMaxCrossAxisExtent控制布局主要用在 GridView.builder 里面 | |
primary | bool | 是否是与父节点的PrimaryScrollController所关联的主滚动视图 | |
physics | ScrollPhysics | 滚动的视图如何响应用户的输入 | |
shrinkWrap | bool | false | 滚动方向的滚动视图内容是否应该由正在查看的内容所决定 |
cacheExtent | double | 缓存区域 |
使用GridView.count构建网格列表,示例代码如下:
GridView.count(
padding: EdgeInsets.all(16.0),
crossAxisCount: 3,//一行上放三列数据
crossAxisSpacing: 8.0,//水平距离
mainAxisSpacing: 8.0,//垂直距离
children: <Widget>[
ItemDemo(title: "网格列表一",icon: IconData(0xe800, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表二",icon: IconData(0xe801, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表三",icon: IconData(0xe802, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表四",icon: IconData(0xe803, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表五",icon: IconData(0xe804, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表六",icon: IconData(0xe805, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表七",icon: IconData(0xe806, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表八",icon: IconData(0xe807, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表九",icon: IconData(0xf008, fontFamily: 'MyFlutterApp'),),
],
),
效果如下图所示:
使用GridView.extent构建网格列表,示例代码如下:
GridView.extent(
padding: EdgeInsets.all(16.0),
maxCrossAxisExtent: 200.0,//最大宽度
crossAxisSpacing: 8.0,//水平距离
mainAxisSpacing: 8.0,//垂直距离
children: <Widget>[
ItemDemo(title: "网格列表一",icon: IconData(0xe800, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表二",icon: IconData(0xe801, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表三",icon: IconData(0xe802, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表四",icon: IconData(0xe803, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表五",icon: IconData(0xe804, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表六",icon: IconData(0xe805, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表七",icon: IconData(0xe806, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表八",icon: IconData(0xe807, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表九",icon: IconData(0xf008, fontFamily: 'MyFlutterApp'),),
],
),
效果图如下所示:
GridView还有一个gridDelegate参数,类型是SliverGridDelegate。Flutter中提供了两个SliverGridDelegate的子类SliverGridDelegateWithFixedCrossAxisCount和SliverGridDelegateWithMaxCrossAxisExtent,我们可以使用,效果和GridView.count和GridView.extent的效果是一样的。
SliverGridDelegateWithFixedCrossAxisCount的使用,示例代码如下所示:
GridView(
padding: EdgeInsets.all(16.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3 , //一行上放三列数据
childAspectRatio:1.5,//宽高比
crossAxisSpacing: 8.0,//水平距离
mainAxisSpacing: 8.0,//垂直距离
),
children: <Widget>[
ItemDemo(title: "网格列表一",icon: IconData(0xe800, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表二",icon: IconData(0xe801, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表三",icon: IconData(0xe802, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表四",icon: IconData(0xe803, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表五",icon: IconData(0xe804, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表六",icon: IconData(0xe805, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表七",icon: IconData(0xe806, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表八",icon: IconData(0xe807, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表九",icon: IconData(0xf008, fontFamily: 'MyFlutterApp'),),
],
)
注意:元素的大小是通过crossAxisCount和childAspectRatio来决定的
效果图如下所示:
SliverGridDelegateWithMaxCrossAxisExtent的使用,示例代码如下所示:
GridView(
padding: EdgeInsets.all(16.0),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200 , //最大宽度
childAspectRatio:2,//宽高比
crossAxisSpacing: 8.0,//水平距离
mainAxisSpacing: 8.0,//垂直距离
),
children: <Widget>[
ItemDemo(title: "网格列表一",icon: IconData(0xe800, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表二",icon: IconData(0xe801, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表三",icon: IconData(0xe802, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表四",icon: IconData(0xe803, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表五",icon: IconData(0xe804, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表六",icon: IconData(0xe805, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表七",icon: IconData(0xe806, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表八",icon: IconData(0xe807, fontFamily: 'MyFlutterApp'),),
ItemDemo(title: "网格列表九",icon: IconData(0xf008, fontFamily: 'MyFlutterApp'),),
],
)
效果图如下所示:
GridView.builder
如果GridView需要展示的数据很多的话,我们可以通过GridView.builder方法来构建网格列表,示例代码如下:
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1.4,
mainAxisSpacing: 8.0,
crossAxisSpacing: 8.0,
),
itemCount: posts.length,
itemBuilder: _itemBuilder),
Widget _itemBuilder(BuildContext context, int index) {
return Container(
color: Colors.greenAccent,
child: Stack(
children: <Widget>[
Image.network(posts[index].imageUrl,fit: BoxFit.cover,),
Center(
child: Text(posts[index].title,style: TextStyle(
fontSize: 16.0,
),),
),
],
),
);
}
效果图如下图所示:
到这里关于列表的到这里差不多就结束,我们下篇博客讲解一下关于按钮方面的知识。