Flutter ListView 与滚动
ListView 是 Flutter 中最常用的滚动列表 Widget,用于显示可滚动的内容列表。
ListView 基本用法
实例:ListView 基本用法
// 方式1:children 参数(适用于少量项目)
ListView(
children: [
ListTile(title: Text('第一项')),
ListTile(title: Text('第二项')),
ListTile(title: Text('第三项')),
],
)
// 方式2:ListView.builder(适用于大量或无限列表)
ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
)
// 方式3:ListView.separated(带分隔符)
ListView.separated(
itemCount: 10,
separatorBuilder: (context, index) => const Divider(), // 分隔线
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
)
ListView(
children: [
ListTile(title: Text('第一项')),
ListTile(title: Text('第二项')),
ListTile(title: Text('第三项')),
],
)
// 方式2:ListView.builder(适用于大量或无限列表)
ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
)
// 方式3:ListView.separated(带分隔符)
ListView.separated(
itemCount: 10,
separatorBuilder: (context, index) => const Divider(), // 分隔线
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
)
ListView 常用属性
| 属性 | 说明 |
|---|---|
| scrollDirection | 滚动方向,默认为 Axis.vertical(垂直) |
| reverse | 是否反向滚动 |
| padding | 列表内边距 |
| itemExtent | 固定项目高度,可提升性能 |
| prototypeItem | 原型项目,用于计算高度 |
实例:横向 ListView
// 横向滚动列表
SizedBox(
height: 120, // 必须设置高度
child: ListView.builder(
scrollDirection: Axis.horizontal, // 横向滚动
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: 100,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Colors.blue[100],
child: Center(
child: Text('项 $index'),
),
);
},
),
)
SizedBox(
height: 120, // 必须设置高度
child: ListView.builder(
scrollDirection: Axis.horizontal, // 横向滚动
itemCount: 20,
itemBuilder: (context, index) {
return Container(
width: 100,
margin: const EdgeInsets.symmetric(horizontal: 8),
color: Colors.blue[100],
child: Center(
child: Text('项 $index'),
),
);
},
),
)
GridView - 网格布局
GridView 用于创建二维网格列表。
实例:GridView 用法
// GridView.count - 固定列数
GridView.count(
crossAxisCount: 3, // 3 列
children: List.generate(20, (index) {
return Container(
margin: const EdgeInsets.all(4),
color: Colors.blue[100],
child: Center(child: Text('${index + 1}')),
);
}),
)
// GridView.builder - 动态构建
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 4 列
mainAxisSpacing: 8, // 垂直间距
crossAxisSpacing: 8, // 水平间距
childAspectRatio: 1, // 宽高比
),
itemCount: 50,
itemBuilder: (context, index) {
return Container(
color: Colors.green[100],
child: Center(child: Text('${index + 1}')),
);
},
)
// GridView.extent - 自适应列数
GridView.extent(
maxCrossAxisExtent: 150, // 最大列宽
children: List.generate(20, (index) {
return Container(
margin: const EdgeInsets.all(4),
color: Colors.orange[100],
child: Center(child: Text('${index + 1}')),
);
}),
)
GridView.count(
crossAxisCount: 3, // 3 列
children: List.generate(20, (index) {
return Container(
margin: const EdgeInsets.all(4),
color: Colors.blue[100],
child: Center(child: Text('${index + 1}')),
);
}),
)
// GridView.builder - 动态构建
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4, // 4 列
mainAxisSpacing: 8, // 垂直间距
crossAxisSpacing: 8, // 水平间距
childAspectRatio: 1, // 宽高比
),
itemCount: 50,
itemBuilder: (context, index) {
return Container(
color: Colors.green[100],
child: Center(child: Text('${index + 1}')),
);
},
)
// GridView.extent - 自适应列数
GridView.extent(
maxCrossAxisExtent: 150, // 最大列宽
children: List.generate(20, (index) {
return Container(
margin: const EdgeInsets.all(4),
color: Colors.orange[100],
child: Center(child: Text('${index + 1}')),
);
}),
)
滚动控制
使用 ScrollController 可以控制滚动位置。
实例:滚动控制
class ScrollExample extends StatefulWidget {
const ScrollExample({super.key});
@override
State<ScrollExample> createState() => _ScrollExampleState();
}
class _ScrollExampleState extends State<ScrollExample> {
// 创建滚动控制器
late ScrollController _controller;
@override
void initState() {
super.initState();
_controller = ScrollController();
// 监听滚动事件
_controller.addListener(() {
print('滚动位置: ${_controller.offset}');
});
}
@override
void dispose() {
// 销毁控制器
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
// 滚动到顶部按钮
ElevatedButton(
onPressed: () {
// 滚动到顶部
_controller.animateTo(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
},
child: const Text('滚动到顶部'),
),
// 列表
Expanded(
child: ListView.builder(
controller: _controller, // 绑定控制器
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
),
),
],
);
}
}
const ScrollExample({super.key});
@override
State<ScrollExample> createState() => _ScrollExampleState();
}
class _ScrollExampleState extends State<ScrollExample> {
// 创建滚动控制器
late ScrollController _controller;
@override
void initState() {
super.initState();
_controller = ScrollController();
// 监听滚动事件
_controller.addListener(() {
print('滚动位置: ${_controller.offset}');
});
}
@override
void dispose() {
// 销毁控制器
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
// 滚动到顶部按钮
ElevatedButton(
onPressed: () {
// 滚动到顶部
_controller.animateTo(
0,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
},
child: const Text('滚动到顶部'),
),
// 列表
Expanded(
child: ListView.builder(
controller: _controller, // 绑定控制器
itemCount: 100,
itemBuilder: (context, index) {
return ListTile(title: Text('第 ${index + 1} 项'));
},
),
),
],
);
}
}
Slivers 高级滚动
CustomScrollView 配合 Slivers 可以实现更复杂的滚动效果。
实例:Slivers 实现折叠效果
// 带折叠应用栏的滚动视图
CustomScrollView(
slivers: [
// 折叠应用栏
SliverAppBar(
expandedHeight: 200, // 展开高度
pinned: true, // 固定在顶部
flexibleSpace: FlexibleSpaceBar(
title: const Text('折叠标题'),
background: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
),
),
),
// 列表内容
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('第 ${index + 1} 项')),
childCount: 30,
),
),
],
)
// 网格 Sliver
CustomScrollView(
slivers: [
const SliverAppBar(
title: Text('图片网格'),
pinned: true,
),
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
child: Image.network('https://picsum.photos/200?$index'),
),
childCount: 20,
),
),
],
)
CustomScrollView(
slivers: [
// 折叠应用栏
SliverAppBar(
expandedHeight: 200, // 展开高度
pinned: true, // 固定在顶部
flexibleSpace: FlexibleSpaceBar(
title: const Text('折叠标题'),
background: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.blue, Colors.purple],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
),
),
),
),
// 列表内容
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) => ListTile(title: Text('第 ${index + 1} 项')),
childCount: 30,
),
),
],
)
// 网格 Sliver
CustomScrollView(
slivers: [
const SliverAppBar(
title: Text('图片网格'),
pinned: true,
),
SliverGrid(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
child: Image.network('https://picsum.photos/200?$index'),
),
childCount: 20,
),
),
],
)
Slivers 提供了一种高效的方式来处理大量滚动项目,它们只渲染可见区域的项目,从而提供良好的性能。
