1328 字
7 分钟
Flutter Day03: 常用滚动组件
Flutter Day03 - 常用滚动组件笔记
1. SingleChildScrollView
1.1 组件作用
- 让单个子组件具备滚动能力。
- 常见搭配是
Column,用于承载一组内容块。
1.2 适用场景
- 长表单。
- 设置页。
- 内容总量不大但高度不固定的页面。
1.3 特点
- 子节点会一次性渲染完成。
- 代码简单,适合中小体量内容。
- 数据量很大时性能不如
ListView.builder。
1.4 代码引用(你的示例)
import 'package:flutter/material.dart';
void main() { runApp(const MySingleChildScrollView());}
class MySingleChildScrollView extends StatefulWidget { const MySingleChildScrollView({super.key});
@override State<MySingleChildScrollView> createState() => _MySingleChildScrollViewState();}
class _MySingleChildScrollViewState extends State<MySingleChildScrollView> { ScrollController _scrollController = ScrollController();
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('SingleChildScrollView')), body: Stack( children: [ SingleChildScrollView( controller: _scrollController, padding: const EdgeInsets.all(20), child: Column( children: List.generate(100, (index) { return Container( margin: const EdgeInsets.only(top: 10), alignment: Alignment.center, width: double.infinity, height: 100, color: Colors.blue, child: Text( "Item $index", style: const TextStyle(color: Colors.white, fontSize: 20), ), ); }), ), ), Positioned( bottom: 20, right: 20, child: GestureDetector( onTap: () { _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration(seconds: 1), curve: Curves.easeInOut, ); }, child: Container( height: 80, width: 80, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(40), ), alignment: Alignment.center, child: const Text( "跳转底部", style: TextStyle(color: Colors.white, fontSize: 16), ), ), ), ), Positioned( top: 20, right: 20, child: GestureDetector( onTap: () { _scrollController.animateTo( _scrollController.position.minScrollExtent, duration: const Duration(seconds: 1), curve: Curves.easeInOut, ); }, child: Container( height: 80, width: 80, decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(40), ), alignment: Alignment.center, child: const Text( "跳转顶部", style: TextStyle(color: Colors.white, fontSize: 16), ), ), ), ), ], ), ), ); }}1.5 关键点总结
ScrollController可控制滚动位置。animateTo有动画,jumpTo无动画。Stack + Positioned可以叠加悬浮按钮(顶部/底部跳转)。
1.6 常用属性知识点及应用
| 属性 | 说明 | 常见应用 |
|---|---|---|
controller | 绑定滚动控制器 | 点击按钮回到顶部/底部、监听滚动位置 |
scrollDirection | 滚动方向,默认纵向 | 横向图片流可设置为 Axis.horizontal |
reverse | 是否反向滚动 | 聊天列表需要从底部开始时可用 |
padding | 内容内边距 | 页面留白、避免内容贴边 |
physics | 滚动行为 | 使用 BouncingScrollPhysics 实现 iOS 弹性效果 |
child | 单个子组件 | 通常放 Column、Form 等组合内容 |
应用示例:
SingleChildScrollView( controller: _scrollController, scrollDirection: Axis.vertical, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), physics: const BouncingScrollPhysics(), child: Column( children: const [ Text('表单标题'), SizedBox(height: 12), Text('更多内容...'), ], ),)2. ListView.builder
2.1 组件作用
- 构建长列表。
- 按需渲染可见区域的 item,提高性能。
2.2 适用场景
- 数据量较大列表。
- 列表项结构基本一致。
2.3 代码引用(你的示例)
class MyListView1 extends StatefulWidget { const MyListView1({super.key});
@override State<MyListView1> createState() => _MyListViewState1();}
class _MyListViewState1 extends State<MyListView1> { ScrollController _scrollController = ScrollController();
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("ListView.builder")), body: ListView.builder( itemCount: 100, itemBuilder: (BuildContext context, int index) { return Container( margin: EdgeInsets.only(top: 10), alignment: Alignment.center, width: double.infinity, height: 100, color: Colors.blue, child: Text( "Item $index", style: TextStyle(color: Colors.white, fontSize: 20), ), ); }, padding: EdgeInsets.all(20), ), ), ); }}2.4 关键参数
itemCount: 列表总项数。itemBuilder: 按索引构建每一项。padding: 列表内边距。
2.5 常用属性知识点及应用
| 属性 | 说明 | 常见应用 |
|---|---|---|
itemCount | 列表项数量 | 避免无限构建,明确数据边界 |
itemBuilder | 按索引构建 item | 大列表按需渲染,减少内存占用 |
controller | 列表滚动控制器 | 上拉分页、回到顶部、读取偏移量 |
scrollDirection | 滚动方向 | 横向商品卡片列表 |
padding | 列表留白 | 内容布局更美观 |
physics | 滚动物理效果 | 禁止滚动可用 NeverScrollableScrollPhysics |
shrinkWrap | 按内容收缩尺寸 | 嵌套在 Column 时常用(注意性能) |
应用示例:
ListView.builder( controller: _scrollController, itemCount: 100, padding: const EdgeInsets.all(16), physics: const AlwaysScrollableScrollPhysics(), itemBuilder: (context, index) { return ListTile( title: Text('Item $index'), ); },)3. ListView.separated
3.1 组件作用
- 与
ListView.builder一样按需渲染。 - 额外提供分割线构建函数。
3.2 适用场景
- 需要明确区分 item 与 item 的列表。
- 例如:订单列表、消息列表、设置分组项。
3.3 代码引用(你的示例)
class MyListView2 extends StatefulWidget { const MyListView2({super.key});
@override State<MyListView2> createState() => _MyListViewState2();}
class _MyListViewState2 extends State<MyListView2> { ScrollController _scrollController = ScrollController();
@override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text("ListView.separated")), body: ListView.separated( itemCount: 100, itemBuilder: (BuildContext context, int index) { return Container( alignment: Alignment.center, width: double.infinity, height: 100, color: Colors.blue, child: Text( "Item $index", style: TextStyle(color: Colors.white, fontSize: 20), ), ); }, separatorBuilder: (BuildContext context, int index) { return Container( height: 1, color: Colors.grey, ); }, padding: EdgeInsets.all(20), ), ), ); }}3.4 关键参数
itemBuilder: 构建列表项。separatorBuilder: 构建分割线。itemCount: 列表项数量。
3.5 常用属性知识点及应用
| 属性 | 说明 | 常见应用 |
|---|---|---|
itemCount | item 数量 | 与后端数据长度保持一致 |
itemBuilder | 构建每个列表项 | 渲染消息、订单、评论等结构化数据 |
separatorBuilder | 构建分割区域 | 分割线、分组间距、时间分隔条 |
controller | 滚动控制 | 无限加载、回滚定位 |
padding | 列表内边距 | 统一页面边距规范 |
physics | 滚动行为控制 | 嵌套滚动时配置更稳定 |
应用示例:
ListView.separated( itemCount: 20, padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), itemBuilder: (context, index) { return ListTile( title: Text('消息 $index'), subtitle: const Text('这是一条消息预览'), ); }, separatorBuilder: (context, index) { return const Divider(height: 1); },)4. 三种滚动组件对比
| 组件 | 渲染方式 | 适合场景 | 优点 | 注意点 |
|---|---|---|---|---|
| SingleChildScrollView | 一次性渲染全部内容 | 内容不多、结构灵活页面 | 使用简单 | 内容太多会影响性能 |
| ListView.builder | 按需渲染 | 长列表、大数据量 | 性能好 | item 结构建议稳定 |
| ListView.separated | 按需渲染 + 分隔构建 | 需要分割线的长列表 | 结构清晰 | 分隔线逻辑单独维护 |
5. 学习小结
- 页面内容总量少:优先
SingleChildScrollView。 - 大数据列表:优先
ListView.builder。 - 大数据且要分隔效果:优先
ListView.separated。 - 需要程序化滚动控制时,搭配
ScrollController。
Flutter Day03: 常用滚动组件
https://zgq1008.github.io/posts/flutter/flutter_day03/ Flutter 系列导航