Flutter--List列表组件
列表布局是我们项目开发中最常用的一种布局方式。Flutter中我们可以通过ListView来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。列表有如下分类:
(1)垂直列表
(2)垂直图文列表
(3)水平列表
(4)动态列表
列表组件的常用参数: (1) scrollDirection Axis Axis.horizontal表示水平列表,Axis.vertical垂直列表 (2) padding EdgeInsetsGeometry 内边距 (3) resolve bool 组件反向排序 (4) children List 列表元素
1.垂直列表
(1)最简单的实现
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
Divider(),
ListTile(
title: Text('我是一个列表'),
),
],
);
}
}
使用ListTile可以配合ListView快速实现垂直列表的效果。
(2)带图标的垂直列表
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView(
children: const [
ListTile(
leading: Icon(Icons.home,color: Colors.blue,),
title: Text('首页'),
trailing: Icon(Icons.chevron_right_sharp),
),
Divider(),
ListTile(
leading: Icon(Icons.assessment,color: Colors.orange,),
title: Text('订单'),
trailing: Icon(Icons.chevron_right_sharp),
),
Divider(),
],
);
}
}
这里,我们可以通过leading和trailing分别设置左侧和最右侧的图标。
2.垂直图文列表
(1)新闻列表
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.fromLTRB(0,10, 0, 0),
children: [
ListTile(
leading: Image.network('https://www.itying.com/images/flutter/1.png'),
title: const Text('这是一个新闻标题'),
subtitle: const Text('副标题'),
),
const Divider(),
ListTile(
leading: Image.network('https://www.itying.com/images/flutter/2.png'),
title: const Text('这是一个新闻标题'),
),
const Divider(),
ListTile(
leading: Image.network('https://www.itying.com/images/flutter/3.png'),
title: const Text('这是一个新闻标题'),
),
const Divider(),
ListTile(
leading: Image.network('https://www.itying.com/images/flutter/4.png'),
title: const Text('这是一个新闻标题'),
),
],
);
}
}
如图,这样我们就可以实现简单实现一个图文列表。
(2)图片列表 我们不仅仅可以使用上述的ListTile实现图片列表,使用Image和Text也是可以实现图文列表的。
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
children: [
Image.network('https://www.itying.com/images/flutter/1.png'),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: const Text(
'这是一个标题',
style: TextStyle(fontSize: 22.0),
textAlign: TextAlign.center,
),
),
Image.network('https://www.itying.com/images/flutter/2.png'),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: const Text(
'这是一个标题',
style: TextStyle(fontSize: 22.0),
textAlign: TextAlign.center,
),
),
Image.network('https://www.itying.com/images/flutter/3.png'),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: const Text(
'这是一个标题',
style: TextStyle(fontSize: 22.0),
textAlign: TextAlign.center,
),
),
Image.network('https://www.itying.com/images/flutter/4.png'),
Container(
height: 44,
padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
child: const Text(
'这是一个标题',
style: TextStyle(fontSize: 22.0),
textAlign: TextAlign.center,
),
),
],
);
}
}
3.水平列表
通过指定ListView的scrollDirection,我们可以实现水平滑动的列表:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return SizedBox(
height: 120,
child: ListView(
scrollDirection: Axis.horizontal,
children: [
Container(
width: 120,
decoration: const BoxDecoration(color: Colors.red),
child: Column(
children: [
SizedBox(
height: 90,
child: Image.network('https://www.itying.com/images/flutter/1.png',fit: BoxFit.cover,),
),
const Text('我是标题'),
],
),
),
Container(
width: 120,
decoration: const BoxDecoration(color: Colors.green),
child: Column(
children: [
SizedBox(
height: 90,
child: Image.network('https://www.itying.com/images/flutter/2.png',fit: BoxFit.cover,),
),
const Text('我是标题'),
],
),
),
Container(
width: 120,
decoration: const BoxDecoration(color: Colors.yellow),
child: Column(
children: [
SizedBox(
height: 90,
child: Image.network('https://www.itying.com/images/flutter/3.png',fit: BoxFit.cover,),
),
const Text('我是标题'),
],
),
),
Container(
width: 120,
decoration: const BoxDecoration(color: Colors.pink),
child: Column(
children: [
SizedBox(
height: 90,
child: Image.network('https://www.itying.com/images/flutter/4.png',fit: BoxFit.cover,),
),
const Text('我是标题'),
],
),
),
Container(
width: 120,
decoration: const BoxDecoration(color: Colors.blue),
child: Column(
children: [
SizedBox(
height: 90,
child: Image.network('https://www.itying.com/images/flutter/5.png',fit: BoxFit.cover,),
),
const Text('我是标题'),
],
),
),
],
),
);
}
}
需要注意的就是我们需要在ListView外层嵌套一层,以给ListView设置一个确切的高度。实现水平滑动总体来讲,还是算比较容易的。
4.动态列表
(1)定义一个方法,返回List,赋值给children。
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
List<Widget> _initListData() {
List<Widget> list = [];
for(int i =0;i<20;i++) {
list.add(ListTile(title: Text('数据:$i'),),);
}
return list;
}
@override
Widget build(BuildContext context) {
return ListView(
children: _initListData(),
);
}
}
(2)渲染动态的数组数据
提供动态的数组数据
List dataList = [
{
"author": 'AA',
"title": '这是一个副标题',
"url": 'https://www.itying.com/images/flutter/1.png',
},
{
"author": 'BB',
"title": '这是一个副标题',
"url": 'https://www.itying.com/images/flutter/2.png',
},
{
"author": 'CC',
"title": '这是一个副标题',
"url": 'https://www.itying.com/images/flutter/3.png',
}
];
import 'res/dataList.dart';
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
List<Widget> _initListData() {
List<Widget> list = [];
for (int i = 0; i < dataList.length; i++) {
list.add(
ListTile(
title: Text(dataList[i]['author']),
subtitle: Text(dataList[i]['title']),
leading: Image.network(dataList[i]['url']),
),
);
}
return list;
}
@override
Widget build(BuildContext context) {
return ListView(
children: _initListData(),
);
}
}
上述的我们也可以通过map变换操作来实现:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
List<Widget> _initListData() {
return dataList
.map((value) => ListTile(
title: Text(value['author']),
subtitle: Text(value['author']),
leading: Image.network(value['url']),
))
.toList();
}
@override
Widget build(BuildContext context) {
return ListView(
children: _initListData(),
);
}
}
(3)使用List.builder动态渲染数据
这里还是使用了上述提供的动态数组数据
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: dataList.length, itemBuilder: (context, i) {
return ListTile(
title: Text(dataList[i]['author']),
subtitle: Text(dataList[i]['title']),
leading: Image.network(dataList[i]['url']),
);
});
}
}
同样实现了这样的功能。
转载自:https://juejin.cn/post/7339024907717640255