📋 Flutter 列表网格实战教程
📖 前言
列表和网格是 Flutter 中最常用的布局方式,用于展示大量数据。Flutter 提供了多种列表和网格组件,包括 ListView、GridView、Table、SingleChildScrollView、PageView 等,它们各有特点,适用于不同的场景。

🎯 列表网格组件概览
Flutter 提供了以下列表网格组件:
| ListView | 列表布局 | 一维列表排列 |
| GridView | 网格布局 | 二维网格排列 |
| Table | 表格布局 | 按行列排列 |
| SingleChildScrollView | 单子项滚动 | 内容超出时滚动 |
| PageView | 页面滚动 | 左右滑动切换页面 |
📋 ListView 组件
ListView 是 Flutter 中最常用的列表布局组件,它可以以一维列表的形式排列子组件。
ListView 组件特性
- ✅ 以列表形式排列子组件
- ✅ 支持垂直和水平滚动
- ✅ 支持懒加载(builder)
- ✅ 支持分隔线(separated)
- ✅ 支持自定义滚动行为
基础用法
// 最简单的列表
ListView(
children: [
ListTile(title: Text('项目1')),
ListTile(title: Text('项目2')),
ListTile(title: Text('项目3')),
],
)
// 设置内边距
ListView(
padding: EdgeInsets.all(16),
children: [
ListTile(title: Text('项目1')),
ListTile(title: Text('项目2')),
],
)
// 设置滚动方向
ListView(
scrollDirection: Axis.horizontal, // 水平滚动
children: [
Container(width: 200, child: Text('项目1')),
Container(width: 200, child: Text('项目2')),
],
)

ListView.builder – 懒加载
// 使用 builder 可以懒加载子组件,适合大量数据
ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('项目 $index'),
);
},
)
// 使用 itemExtent 提升性能
ListView.builder(
itemExtent: 50, // 固定高度
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(
title: Text('项目 $index'),
);
},
)
ListView.separated – 带分隔线
ListView.separated(
itemCount: 10,
separatorBuilder: (context, index) => Divider(),
itemBuilder: (context, index) {
return ListTile(
title: Text('项目 $index'),
);
},
)

📊 GridView 组件
GridView 是 Flutter 中用于二维网格布局的组件,它可以以网格形式排列子组件。
GridView 组件特性
- ✅ 以网格形式排列子组件
- ✅ 支持固定列数(count)或固定宽度(extent)
- ✅ 支持懒加载(builder)
- ✅ 支持自定义布局(custom)
- ✅ 支持滚动和分页
基础用法
// GridView.count – 固定列数
GridView.count(
crossAxisCount: 2,
children: [
Container(color: Colors.blue, child: Center(child: Text('1'))),
Container(color: Colors.red, child: Center(child: Text('2'))),
Container(color: Colors.green, child: Center(child: Text('3'))),
Container(color: Colors.orange, child: Center(child: Text('4'))),
],
)
// GridView.count – 设置间距
GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 10,
mainAxisSpacing: 10,
padding: EdgeInsets.all(10),
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
)
// GridView.extent – 固定宽度
GridView.extent(
maxCrossAxisExtent: 150, // 最大宽度
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
)

GridView.builder – 懒加载
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
itemCount: 20,
itemBuilder: (context, index) {
return Container(color: Colors.blue);
},
)

📊 Table 组件
Table 是 Flutter 中用于表格布局的组件,它可以按行和列排列子组件。
Table 组件特性
- ✅ 按行和列排列子组件
- ✅ 支持单元格合并(colSpan 和 rowSpan)
- ✅ 支持设置列宽
- ✅ 支持设置边框和间距
- ✅ 适合显示结构化数据
基础用法
// 最简单的表格
Table(
children: [
TableRow(
children: [
TableCell(child: Text('A1')),
TableCell(child: Text('A2')),
TableCell(child: Text('A3')),
],
),
TableRow(
children: [
TableCell(child: Text('B1')),
TableCell(child: Text('B2')),
TableCell(child: Text('B3')),
],
),
],
)
// 设置边框
Table(
border: TableBorder.all(),
children: [
TableRow(
children: [
TableCell(child: Text('A1')),
TableCell(child: Text('A2')),
],
),
],
)
// 设置列宽
Table(
columnWidths: {
0: FixedColumnWidth(100),
1: FlexColumnWidth(2),
2: FlexColumnWidth(1),
},
children: [
TableRow(
children: [
TableCell(child: Text('A1')),
TableCell(child: Text('A2')),
TableCell(child: Text('A3')),
],
),
],
)

📜 SingleChildScrollView 组件
SingleChildScrollView 是 Flutter 中用于包裹单个子组件并使其可滚动的组件。
SingleChildScrollView 组件特性
- ✅ 包裹单个子组件并使其可滚动
- ✅ 支持垂直和水平滚动
- ✅ 支持自定义滚动行为
- ✅ 适合内容超出屏幕的场景
基础用法
// 最简单的滚动视图
SingleChildScrollView(
child: Column(
children: [
Container(height: 200, color: Colors.blue),
Container(height: 200, color: Colors.red),
Container(height: 200, color: Colors.green),
],
),
)
// 设置内边距
SingleChildScrollView(
padding: EdgeInsets.all(16),
child: Column(
children: [
Text('内容1'),
Text('内容2'),
],
),
)
// 设置滚动方向
SingleChildScrollView(
scrollDirection: Axis.horizontal, // 水平滚动
child: Row(
children: [
Container(width: 200, color: Colors.blue),
Container(width: 200, color: Colors.red),
],
),
)

📄 PageView 组件
PageView 是 Flutter 中用于页面滚动布局的组件,它可以实现左右或上下滑动切换页面的效果。
PageView 组件特性
- ✅ 实现左右或上下滑动切换页面
- ✅ 支持页面控制器(PageController)控制页面切换
- ✅ 支持无限循环滚动
- ✅ 支持自定义页面切换动画
基础用法
// 最简单的页面视图
PageView(
children: [
Container(color: Colors.blue, child: Center(child: Text('页面1'))),
Container(color: Colors.red, child: Center(child: Text('页面2'))),
Container(color: Colors.green, child: Center(child: Text('页面3'))),
],
)
// 设置滚动方向
PageView(
scrollDirection: Axis.vertical, // 垂直滚动
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
)
// 使用 PageController
PageController controller = PageController();
PageView(
controller: controller,
children: [
Container(color: Colors.blue),
Container(color: Colors.red),
],
)
// 跳转到指定页面
controller.jumpToPage(1);

PageView.builder – 懒加载
PageView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return Container(
color: Colors.blue,
child: Center(child: Text('页面 $index')),
);
},
)

💡 实际应用场景
场景1:商品列表
ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ListTile(
leading: Image.network(products[index].imageUrl),
title: Text(products[index].name),
subtitle: Text('¥${products[index].price}'),
trailing: Icon(Icons.arrow_forward_ios),
);
},
)

场景2:图片网格
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
itemCount: images.length,
itemBuilder: (context, index) {
return Image.network(images[index]);
},
)

场景3:数据表格
Table(
border: TableBorder.all(),
children: [
TableRow(
children: [
TableCell(child: Text('姓名')),
TableCell(child: Text('年龄')),
TableCell(child: Text('城市')),
],
),
...users.map((user) => TableRow(
children: [
TableCell(child: Text(user.name)),
TableCell(child: Text('${user.age}')),
TableCell(child: Text(user.city)),
],
)),
],
)

场景4:轮播图
PageView.builder(
itemCount: banners.length,
itemBuilder: (context, index) {
return Image.network(banners[index]);
},
)

⚠️ 常见问题与解决方案
问题1:ListView 性能问题
问题描述:ListView 滚动卡顿。
解决方案:
// 使用 ListView.builder
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
)
// 使用 itemExtent 提升性能
ListView.builder(
itemExtent: 50, // 固定高度
itemCount: items.length,
itemBuilder: (context, index) {
return ListTile(title: Text(items[index]));
},
)
问题2:GridView 列数不固定
问题描述:需要根据屏幕宽度动态调整列数。
解决方案:
GridView.builder(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200, // 最大宽度
crossAxisSpacing: 4,
mainAxisSpacing: 4,
),
itemCount: items.length,
itemBuilder: (context, index) {
return Container(color: Colors.blue);
},
)
问题3:SingleChildScrollView 嵌套 ListView
问题描述:SingleChildScrollView 嵌套 ListView 会导致滚动冲突。
解决方案:
// 使用 shrinkWrap
ListView(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(), // 禁用 ListView 的滚动
children: [
// 子组件
],
)
🎨 最佳实践
1. 组件选择指南
| 一维列表 | ListView |
| 二维网格 | GridView |
| 结构化数据 | Table |
| 单个可滚动内容 | SingleChildScrollView |
| 页面切换 | PageView |
2. 性能优化技巧
// 使用 const 构造函数
const ListTile(title: Text('文本'))
// 使用 itemExtent 固定高度
ListView.builder(
itemExtent: 50,
itemBuilder: (context, index) => ListTile(...),
)
// 使用 RepaintBoundary 隔离重绘
RepaintBoundary(
child: ExpensiveWidget(),
)
📚 总结
通过本教程,我们学习了:
列表和网格是 Flutter 中展示数据的主要方式,掌握好这些组件的用法,能够让你轻松处理各种数据展示场景!
🔗 相关资源
- ListView 官方文档
- GridView 官方文档
- Table 官方文档
- SingleChildScrollView 官方文档
- PageView 官方文档
Happy Coding! 🎨✨ 欢迎加入开源鸿蒙跨平台社区
网硕互联帮助中心





评论前必须登录!
注册