学习内容:
ListView基础:静态列表、动态列表(ListView.builder优化性能)列表项:
ListTile(自带图标、标题、副标题的组件)实践任务:
用
ListView.builder做一个 “新闻列表”:循环显示 10 条新闻(标题 + 副标题)点击列表项跳转到详情页,传当前新闻标题
一、ListView基础:静态列表与动态列表※
1. 什么是ListView※
ListView是Flutter中用于展示滚动列表的核心组件,适用于需要垂直或水平滚动的大量数据战术(如:新闻列表、商品列表、聊天记录等)。
2. 静态列表(ListView直接包含子组件)※
当列表项数较少且固定时,可直接在ListView的children中添加子组件(如:Container、ListTile等)。
代码示例:简单静态列表
import 'package:flutter/material.dart';
// 定义静态列表页面组件
class StaticListViewDemo extends StatelessWidget{
const StaticListViewDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('静态列表示例'),),
body: ListView(
// 页内边距
padding: const EdgeInsets.all(10),
// 所有列表项
children: [
// 列表项1
Container(
height: 60,
color: Colors.yellow[100],
alignment: Alignment.center,
child: const Text('静态列表项1'),
),
const SizedBox(height: 10,), // 列表项间距
// 列表项2
Container(
height: 60,
color: Colors.blue[100],
alignment: Alignment.center,
child: const Text('静态列表项2'),
),
const SizedBox(height: 10,),
// 列表项3
Container(
height: 60,
color: Colors.red[100],
alignment: Alignment.center,
child: const Text('静态列表项3'),
)
],
),
);
}
}
void main() => runApp(App());
class App extends StatelessWidget{
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '静态列表Demo',
home: const StaticListViewDemo(), // 将静态列表设为初始页面
);
}
}- 运行效果

- 静态列表的优缺点
- 优点:写法简单,适合少量固定数据
- 缺点:无论列表项是否可见,都会一次性创建所有组件,数据量大时会严重影响性能
动态列表(ListView.builder按需构建)※
当列表项数量较多或动态变化时(如:10条以上),必须用ListView.builder。它会只创建当前可见的列表项,滚动时再销毁不可见项,极大提升性能。
- ListView.builder核心参数
| 参数名 | 作用 | 类型 |
| itemCount | 列表项总数量(决定循环次数) | int |
| itemBuilder | 列表项构建函数(每次滚动到可见区域时调用) | Widget Function(BuildContext, int) |
- 代码示例:简单动态列表
import 'package:flutter/material.dart';
// 定义动态列表页面组件
class DynamicListViewDemo extends StatelessWidget{
const DynamicListViewDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('动态列表示例'),),
body: ListView.builder(
// 页内边距
padding: const EdgeInsets.all(10),
// 列表项总数量(100条)
itemCount: 100,
// 构建列表项(index是当前项的索引,从0开始)
itemBuilder: (context, index) {
// 每次滚动到可见区域时,才会执行这里的代码
return Container(
height: 60,
color: index % 2 == 0 ? Colors.yellow[100] : Colors.blue[100],
alignment: Alignment.center,
child: Text('动态列表项${index + 1}'),
);
},
),
);
}
}
void main() => runApp(App());
class App extends StatelessWidget{
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '动态列表Demo',
home: const DynamicListViewDemo(), // 将动态列表设为初始页面
);
}
}- 运行效果

- 动态列表的核心优势
- 性能优化:只创建可见项,减少内存占用
- 动态数据适配:配合itemCount可灵活适配数据长度
二、ListTile组件:快速构件列表项※
1. 什么是ListTile※
ListTile是Flutter提供的预定义列表项组件,内置了常用布局(图标、标题、副标题、箭头等),无需手动用Row拼接,适合快速开发列表。
2. ListTile常用属性※
| 属性名 | 作用 | 类型 |
| leading | 左侧图标/组件 | Widget? |
| title | 主标题(大号文本) | Widget? |
| subTitle | 副标题(小号文本,在标题下方) | Widget? |
| trailing | 右侧图标/组件(如:箭头) | Widget? |
| onTap | 点击事件回调 | VoidCallback? |
| contentPadding | 内容内边距 | EdgeInsetsGeometry? |
3. 代码示例:ListTile基本用法※
import 'package:flutter/material.dart';
// 定义动态列表页面组件
class ListTileDemo extends StatelessWidget{
const ListTileDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile示例'),),
body: ListView(
// 页内边距
padding: const EdgeInsets.all(10),
children: [
// 基础列表项(标题 + 副标题)
ListTile(
title: const Text('主标题:新闻标题'),
subtitle: const Text('副标题:这是新闻简要描述...'),
// 点击事件
onTap: () => print('点击了列表项1'),
),
const Divider(height: 1,), // 分割线
// 带左侧图标和右侧箭头的列表项
ListTile(
leading: const Icon(Icons.newspaper, color: Colors.yellow,), // 左侧图标
title: const Text('带图标的标题'),
subtitle: const Text('左侧是新闻图标,右侧是箭头'),
trailing: const Icon(Icons.arrow_forward_ios, size: 16,), // 右侧箭头
onTap: () => print('点击了列表项2'),
),
const Divider(height: 1,)
],
),
);
}
}
void main() => runApp(App());
class App extends StatelessWidget{
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '动态列表Demo',
home: const ListTileDemo(), // 将动态列表设为初始页面
);
}
}- 运行效果

4. ListTile与ListView.builder结合※
在动态列表中使用ListTile,可快速构件统一风格的列表项
import 'package:flutter/material.dart';
// 定义动态列表页面组件
class ListTileWithBuilderDemo extends StatelessWidget{
const ListTileWithBuilderDemo({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('ListTile + ListView.builder示例'),),
body: ListView.builder(
// 页内边距
padding: const EdgeInsets.all(10),
itemCount: 50,
itemBuilder: (context, index) {
return Column(
children: [
ListTile(
leading: Icon(Icons.message, color: Colors.yellow[600],),
title: Text('消息${index + 1}'),
subtitle: const Text('点击查看详情'),
trailing: const Icon(Icons.chevron_right),
onTap: () => print('点击了消息${index + 1}'),
),
const Divider(height: 1,), // 每条列表项下加分割线
],
);
},
),
);
}
}
void main() => runApp(App());
class App extends StatelessWidget{
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '动态列表Demo',
home: const ListTileWithBuilderDemo(), // 将动态列表设为初始页面
);
}
}- 运行效果

三、列表项点击跳转与参数传递※
1. 实现思路※
在ListView.builder中,为每个ListTile的onTap事件绑定路由跳转逻辑,通过Navigator.push跳转到详情页,并传递当前列表项的参数(如:新闻标题)。
2. 实现步骤※
- 步骤1:创建详情页(接收参数)
// pages/news_detail_page.dart
import 'package:flutter/material.dart';
class NewsDetailPage extends StatelessWidget {
// 接收从列表页传递的新闻标题
final String newTitle;
const NewsDetailPage({
super.key,
required this.newTitle
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("新闻详情")),
body: Padding(
padding: const EdgeInsets.all(20),
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 显示传过来的新闻标题
Text(
newTitle,
style: const TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 20,),
const Text('这是新闻的详细内容...'),
const SizedBox(height: 30,),
ElevatedButton(onPressed: () => Navigator.pop(context), child: const Text('返回列表'))
],
),
),
),
);
}
}- 步骤2:在列表中实现点击跳转
// pages/news_list_page.dart
import 'package:flutter/material.dart';
import 'news_detail_page.dart'; // 导入详情页
class NewsListPage extends StatelessWidget {
const NewsListPage({super.key});
@override
Widget build(BuildContext context) {
// 模拟新闻数据(标题 + 副标题)
final List<Map<String, String>> newsData = [
{
"title": " Flutter 3.24 版本发布,新增多项性能优化",
"subtitle": "官方宣布 Flutter 3.24 稳定版发布,重点提升列表渲染性能..."
},
{
"title": "2025 移动开发趋势报告:跨平台框架成主流",
"subtitle": "据行业分析,跨平台开发框架市场占比已达 65%,Flutter 居首..."
},
// 更多数据...
];
return Scaffold(
appBar: AppBar(title: const Text("新闻列表")),
body: ListView.builder(
itemCount: newsData.length,
itemBuilder: (context, index) {
// 获取当前索引的新闻数据
final news = newsData[index];
return Column(
children: [
ListTile(
leading: const Icon(Icons.newspaper, color: Colors.yellow,),
title: Text(
news['title']??'未知标题',
style: const TextStyle(fontWeight: FontWeight.w500),
// 标题过长时显示...
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
subtitle: Text(
news['subtitle']??'', // 新闻副标题
style: const TextStyle(color: Colors.blue, fontSize: 14),
overflow: TextOverflow.ellipsis,
maxLines: 1,
),
trailing: const Icon(Icons.arrow_forward_ios, size: 16,),
// 点击事件:跳转到详情页并传递标题
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewsDetailPage(newTitle: news['title']??'未知标题'), // 传递新闻标题
));
},
),
const Divider(height: 1,) // 分割线
],
);
},
)
);
}
}- 步骤3:配置入口文件
import 'package:flutter/material.dart';
import 'pages/news_list_page.dart';
void main() => runApp(App());
class App extends StatelessWidget{
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '新闻列表Demo',
theme: ThemeData(primarySwatch: Colors.yellow),
home: const NewsListPage(), // 初始页为新闻列表
);
}
}- 运行效果

四、常见问题与解决方案※
1. 列表项内容显示不全或溢出※
- 问题:标题或副标题过长时,文字被截断或溢出屏幕。
- 解决:设置maxLines和overflow属性
Text(
"很长很长的标题...",
maxLines: 1, // 最多显示1行
overflow: TextOverflow.ellipsis, // 超出部分显示...
)2. 列表滚动时性能卡顿※
- 问题:数据量大时,滚动不流畅。
- 解决:
- 确保使用ListView.builder而非静态ListView
- 避免在itemBuilder中执行复杂逻辑或创建大量临时对象
列表项高度固定时,设置itemExtent优化性能
ListView.builder( itemExtent: 80, // 固定每条列表项高度为80px // ...其他参数 )