flutter 种常用的排版方式,ListView 和 GridView,可以看到下面是两个排版的最简单的区别。简单看一下它们的使用方式。
ListView 是列表, ListTile是常用的list 的item的widget
| ListView 的常用属性 | ||
|---|---|---|
| 名称 | 类型 | 说明 |
| scrollDirection | Axis | Axis.horizontal水平列表Axis.vertical垂直列表 |
| padding | EdgeInsetsGeometry | 内边距 |
| resolve | bool | 组件反向排序 |
| children | List | 列表元素 |
| ListTile 的常用属性 | ||
|---|---|---|
| 名称 | 类型 | 说明 |
| leading | Widget | 放在title前的widget,例如姓名前的icon图标,图文列表的图片 |
| title | Widget | 元素的标题 |
| subtitle | Widget | 小标题,其位置在title的下面 |
| trailing | Widget | 放在title后面的的widget,例如姓名前的icon图标,图文列表的图片 |
ListView(
children: <Widget>[
ListTile(
leading: Image.network("https://img0.baidu.com/it/u=823872589,3855820635&fm=253"),
title: const Text('华北黄淮高温雨今起强势登场'),
subtitle: const Text("中国天气网讯 21日开始,华北黄淮高温雨今起强势登场"),
),
const Divider(),
],
)
ListView的动态列表
- 借助循环for ,或者其它的方式向 List 中添加widget,
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
List<Widget> _initListView() { // 私有方法,向list中添加10个listtile
List<Widget> list = [];
for (var i = 0; i < 10; i++) {
list.add(const ListTile(
title: Text("我是一个列表"),
));
}
return list;
}
@override
Widget build(BuildContext context) {
return ListView(
children: _initListView(),// 调用私有方法
);
}
}
- 使用ListView.builder 方法实现
class MyHomePage extends StatelessWidget {
List list = []; // widget list
MyHomePage({Key? key}) : super(key: key) {
for (var i = 0; i < 10; i++) { // 向list中添加10个字符串
list.add("我是一个列表--$i");
}
}
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: list.length, // 元素个数,必传
itemBuilder: (context, index) { // context上下文,index下标
return ListTile( // 返回一个widget
title: Text("${list[index]}"),
);
});
}
}
GridView网格
| GridView 的常用属性 | ||
|---|---|---|
| 名称 | 类型 | 说明 |
| scrollDirection | Axis | Axis.horizontal水平列表Axis.vertical垂直列表 |
| padding | EdgeInsetsGeometry | 内边距 |
| resolve | bool | 组件反向排序 |
| children | List | 列表元素 |
| crossAxisSpacing | double | 水平子元素之间的间距 |
| mainAxisSpacing | double | 垂直子元素之间的间距 |
| crossAxisCount | int | 一行有几个子元素,用在GridView.count 命名构造函数里面 |
| maxCrossAxisExtent | double | 子元素的最大长度,用在GridView.count 命名构造函数里面 |
| childAspectRatio | double | 子widget的宽高比 |
| gridDelegate | SliverGridDelegateWithFixedCrossAxisCount,SliverGridDelegateWithMaxCrossAxisExtent | 控制布局主要用在GridView.builder里面 |
GridView.count 实现网格布局
GridView.count构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以 快速的创建横轴固定数量子元素的GridView
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.count(
crossAxisCount: 3, // 水平子元素数量
childAspectRatio: 1.0, // 宽高比
children: const <Widget>[ // 子元素
Icon(Icons.home),
Icon(Icons.ac_unit),
Icon(Icons.search),
Icon(Icons.settings),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.circle),
],
);
}
}
GridView.extent实现网格布局
GridView.extent构造函数内部使用了SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以 快速的创建横轴子元素为固定最大长度的的GridView。
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GridView.extent(
maxCrossAxisExtent: 80.0, // 最大宽度
childAspectRatio: 1.0, // 宽高比
children: const <Widget>[ // 子元素
Icon(Icons.home),
Icon(Icons.ac_unit),
Icon(Icons.search),
Icon(Icons.settings),
Icon(Icons.airport_shuttle),
Icon(Icons.all_inclusive),
Icon(Icons.beach_access),
Icon(Icons.cake),
Icon(Icons.circle),
],
);
}
}
GridView 动态列表
- SliverGridDelegateWithFixedCrossAxisCount, 它就相当于是GridView.count的
class HomePage extends StatelessWidget {
final List listData = [ // 子元素内容list { 'title': 'windy shop', 'sub': 'windy', 'image': 'https://img0.baidu.com/it/u=823872589,3855820635&fm=253' }, ];
HomePage({Key? key}) : super(key: key);
Widget _getListData(context, index) {
return Container(
decoration: BoxDecoration(
border: Border.all(
color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),
child: Column(
children: <Widget>[
Image.network(listData[index]['imageUrl']),
const SizedBox(height: 12),
Text(
listData[index]['title'],
textAlign: TextAlign.center,
style: const TextStyle(fontSize: 20),
)
],
),
// height: 400, //设置高度没有反应
);
}
@override
Widget build(BuildContext context) {
return GridView.builder(
//注意
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10.0, //水平子 Widget 之间间距
mainAxisSpacing: 10.0, //垂直子 Widget 之间间距
crossAxisCount: 2, //一行的 Widget 数量
),
itemCount: listData.length,
itemBuilder: _getListData,
);
}
}
- SliverGridDelegateWithMaxCrossAxisExtent 它就相当于GridView.extent
GridView.builder(
//注意
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent (
crossAxisSpacing:10, // 水平子 Widget 之间间距
mainAxisSpacing:10,//垂直子 Widget 之间间距
maxCrossAxisExtent: 300,//子元素最大宽度
),
itemCount: listData.length,
itemBuilder: _getListData,
);