Flutter ListView 组件及各种模式
模式构造函数适用场景特点基础列表列表项少、固定一次性构建所有子项,简单但性能差动态列表(推荐)列表项多、动态生成按需构建,性能好,适合长列表带分隔线列表需要 item 间分隔在 builder 基础上增加分隔 widget自定义滚动需要完全控制列表布局使用,高级用法水平列表横向滑动内容比如轮播图、横向菜单。
·
Flutter ListView 组件及各种模式
一、ListView 是什么?
在 Flutter 中,ListView 是一个用于展示 可滚动列表 的基础组件,它是最常用的滚动组件之一。
你可以把它理解为:
类似于 Android 的
RecyclerView或 iOS 的UITableView,用于在竖直或水平方向上展示一系列可滚动的条目(items)。
二、ListView 的基本用法
1. 最简单的垂直列表(默认方向)
ListView(
children: [
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
ListTile(title: Text('Item 3')),
],
)
children: 是一个 Widget 列表,代表你要展示的所有子项。- 默认是 垂直滚动(从上到下)。
三、ListView 的几种构造函数(模式)
Flutter 提供了 多个 ListView 的构造函数,每种适用于不同的使用场景。主要包括:
| 构造函数 | 适用场景 | 特点 |
|---|---|---|
| ListView | 子项数量较少、已知全部子项 | 直接传入 children列表 |
| ListView.builder | 子项数量较多或动态生成(推荐) | 按需构建,性能更好,适合长列表 |
| ListView.separated | 需要在每个 item 之间添加分隔线或间隔 | 在 builder 基础上增加分隔 widget |
| ListView.custom | 需要完全自定义滚动行为和 item 布局 | 使用 SliverChildDelegate,高级用法 |
我们重点讲解前面 3 种,也是实际开发中最常用的。
四、1. ListView(直接传 children,适合少量固定列表)
用法:
ListView(
children: [
ListTile(title: Text('首页')),
ListTile(title: Text('发现')),
ListTile(title: Text('我的')),
Container(height: 100, color: Colors.amber, child: Center(child: Text('其他内容'))),
],
)
特点:
- 适合 列表项数量少、固定不变 的情况。
- 所有的子 Widget 会 一次性构建,如果列表很长(比如 1000 个),会导致性能问题,甚至卡顿。
五、2. ListView.builder(推荐:动态/长列表,按需构建)
用法:
ListView.builder(
itemCount: 20, // 列表项总数
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Icon(Icons.star),
title: Text('Item $index'),
);
},
)
参数说明:
| 参数 | 说明 |
|---|---|
itemCount |
列表中有多少项 |
itemBuilder |
回调函数,返回每一项的 Widget,参数是 context和当前索引 index |
特点:
- 按需构建(懒加载),只构建当前屏幕可见的 item,极大提升性能,是开发长列表的首选。
- 适合:从网络/数据库加载的数据列表、聊天记录、商品列表等动态内容。
六、3. ListView.separated(带分隔线的列表)
用法:
ListView.separated(
itemCount: 10,
separatorBuilder: (BuildContext context, int index) {
return Divider(color: Colors.grey); // 分隔线
},
itemBuilder: (BuildContext context, int index) {
return ListTile(
title: Text('Item $index'),
);
},
)
参数说明:
separatorBuilder: 用于构建 每一项之间的分隔 Widget,比如Divider或SizedBox。- 其它参数同
ListView.builder。
效果:
- 每个 item 之间会显示一个分割线(或其他你定义的间隔组件)。
- 常用于:列表需要明显区分每一项的场景,如设置页、通讯录等。
七、ListView 的滚动方向
默认是 垂直滚动(Axis.vertical),但也可以设置为 水平滚动(Axis.horizontal),通常配合 ListView.builder使用。
水平滚动的例子(横向列表):
ListView.builder(
scrollDirection: Axis.horizontal, // 水平滚动
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 100,
margin: EdgeInsets.all(8),
color: Colors.primaries[index % Colors.primaries.length],
alignment: Alignment.center,
child: Text('Item $index'),
);
},
)
说明:
scrollDirection: Axis.horizontal让列表横向滚动- 每个 item 需要指定宽度(比如
width: 100),否则会挤在一起
八、ListView 常用搭配组件
| 组件 | 说明 | 适用场景 |
|---|---|---|
| ListTile | 带图标、标题、副标题的列表项 | 设置页、菜单列表等 |
| Container | 自定义布局容器 | 列表项内容布局 |
| Card | 带阴影的卡片容器 | 商品列表、内容卡片 |
| Divider / SizedBox | 分隔线或间距 | 分隔列表项 |
| GridView | 网格布局(二维列表) | 图片墙、瀑布流等 |
| SliverList | 高级自定义滚动列表(在 CustomScrollView 中使用) | 复杂滚动布局 |
九、ListView 与其它滚动组件的关系
| 组件 | 说明 |
|---|---|
| ListView | 基本的垂直/水平列表 |
| SingleChildScrollView + Column | 简单滚动容器,但子项全部构建,不适合长列表 |
| CustomScrollView + SliverList | 更加灵活的自定义滚动视图,ListView 是其一种实现 |
| GridView | 网格形式的滚动列表 |
| PageView | 页面横向滑动(比如引导页) |
十、ListView 性能优化建议
| 优化点 | 建议 |
|---|---|
| 列表项很多? | 一定要用 ListView.builder或 separated,不要用 ListView(children: []) |
| 图片加载慢? | 使用 cached_network_image等图片缓存库 |
| cell 复杂? | 减少嵌套,优化 widget tree,考虑使用 const构造函数 |
| 数据来自网络? | 结合 FutureBuilder或状态管理(如 Provider、Riverpod、Bloc)异步加载 |
| 滚动卡顿? | 检查是否一次性构建太多 widget,尽量使用懒加载模式 |
十一、总结:ListView 的几种模式对比
| 模式 | 构造函数 | 适用场景 | 特点 |
|---|---|---|---|
| 基础列表 | ListView(children: []) |
列表项少、固定 | 一次性构建所有子项,简单但性能差 |
| 动态列表(推荐) | ListView.builder |
列表项多、动态生成 | 按需构建,性能好,适合长列表 |
| 带分隔线列表 | ListView.separated |
需要 item 间分隔 | 在 builder 基础上增加分隔 widget |
| 自定义滚动 | ListView.custom |
需要完全控制列表布局 | 使用 SliverChildDelegate,高级用法 |
| 水平列表 | ListView(scrollDirection: Axis.horizontal) |
横向滑动内容 | 比如轮播图、横向菜单 |
十二、完整示例:一个实用的 ListView.builder 列表
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('ListView 示例')),
body: MyListView(),
),
);
}
}
class MyListView extends StatelessWidget {
final List<String> items = List.generate(50, (index) => '列表项 ${index + 1}');
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(
leading: Icon(Icons.article),
title: Text(items[index]),
onTap: () {
print('你点击了:${items[index]}');
},
);
},
);
}
}
更多推荐

所有评论(0)