Flutter 无限列表实战:基于 ListView.builder 懒加载机制的 Infinite List 示例深度解析
示例工程移动开发【免费下载链接】flutter-examples[Examples] Simple basic isolated apps, for budding flutter devs.项目地址https://gitcode.com/gh_mirrors/fl/flutter-examples点击查看免费下载导读本文以 flutter-examples 仓库中的 infinite_list 独立示例应用为核心系统讲解在 Flutter 中实现无限列表Infinite List的完整思路借助ListView.builder的按需构建懒加载特性配合数据源的动态追加即可在保持流畅滚动性能的前提下呈现永远加载不完的长列表。读完本文你将掌握惰性列表构建的核心原理、交替行布局的索引换算技巧以及基于状态管理的收藏交互并可直接复用 infinite_list 的工程骨架应用到自己的项目中。一、示例项目定位与核心思想infinite_list是 flutter-examples 仓库中一个聚焦单一功能的独立示例应用其 README 开篇即点明项目目标Example app showing implementation of an infinite list展示无限列表实现的示例应用。所谓无限列表指的是列表内容在用户持续滚动时不断增长、看似没有终点的交互形态典型场景包括信息流、聊天记录、日志流、随机内容生成器等。在 Flutter 中实现无限列表并不需要复杂的分页库核心思想只有两条按需构建列表控件只渲染当前视口内可见的条目而非一次性构建全部数据数据按需追加当滚动接近末尾时为数据源补充新数据驱动列表继续增长。这两条核心思想在本示例中体现得极为纯粹——整个业务逻辑全部集中在单个文件 infinite_list/lib/main.dart 中没有任何第三方状态管理依赖非常适合初学者精读。二、工程骨架与依赖配置在深入代码之前先看工程的依赖与构建配置这决定了示例的运行前提。2.1 依赖声明pubspec.yamlinfinite_list/pubspec.yaml 是本示例的依赖清单关键内容如下name: infinite_list description: An infinite list using flutter environment: sdk: 2.12.0 3.0.0 dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.0 english_words: ^3.1.0需要特别说明两点english_words: ^3.1.0是本示例唯一的功能性第三方依赖。它提供了generateWordPairs()等 API用于生成随机的英文单词组合WordPair充当无限列表的数据来源。^3.1.0 表示允许解析 3.1.0 及以上、但小于 4.0.0 的版本。Dart SDK 约束2.12.0 3.0.0表明该工程建立在空安全Null Safety时代的版本区间之上代码采用空安全友好的写法如使用final初始化容器、未对可变状态使用late声明。工程未引入任何列表分页、无限滚动类第三方库无限列表效果完全由 Flutter 框架内置能力实现这正是该示例的教学价值所在。2.2 Android 端构建配置app/build.gradleinfinite_list/android/app/build.gradle 中defaultConfig声明的applicationId github.nisrulz.infinitelist遵循了本仓库所有示例统一的包名规范github.nisrulz.app_name同时minSdkVersion 16、targetSdkVersion 29、compileSdkVersion 29给出了本示例当前的 Android 最低/目标系统要求。若要在自己的机器上复现请确保本机 Flutter SDK 版本能匹配该工程年代对应的构建链路。2.3 获取依赖与运行在 infinite_list 目录下依次执行# 1. 拉取 pubspec.yaml 中声明的依赖 flutter packages get # 2. 连接设备或模拟器后运行 flutter run仓库根目录还提供了批量脚本 get_packages.sh它会遍历所有含pubspec.yaml的子目录并逐个执行flutter packages get适合一次性为整个仓库的示例工程拉取依赖。三、核心实现剖析ListView.builder 的懒加载机制无限列表的灵魂在 infinite_list/lib/main.dart 的_buildSuggestions()方法中。先看状态类的数据结构main.dartclass RandomWordsState extends StateRandomWords { final _suggestions WordPair[]; final _saved SetWordPair(); final _biggerFont const TextStyle(fontSize: 18.0); ... }_suggestions已生成的 WordPair 数据源列表它是整个无限列表的弹药库_saved收藏集合用于记录用户点击心形图标的条目_biggerFont列表项文字样式。3.1 按需构建的入口ListView.builderWidget _buildSuggestions() { return ListView.builder( padding: const EdgeInsets.all(16.0), itemBuilder: (context, i) { // ... }); }与ListView(children: [...])一次性构建所有子项不同ListView.builder采用惰性构建策略itemBuilder回调只会在列表需要渲染某个索引对应的条目时才会被调用因此无论数据源增长到多大内存中始终只保留视口附近可见的 widget。这是 Flutter 官方推荐的性能最佳实践也是本示例能在无限增长数据的同时保持流畅的根本原因。3.2 交替行布局索引换算技巧itemBuilder的索引i同时涵盖了列表项和分隔线两类内容源码通过奇偶判断实现交替布局main.dartitemBuilder: (context, i) { // 奇数索引渲染一条 1 像素高的分隔线 if (i.isOdd) return Divider(); // i ~/ 2 整除 21, 2, 3, 4, 5 变为 0, 1, 1, 2, 2 // 即换算回真实的数据条目索引剔除分隔线占用的索引位 final index i ~/ 2; // 如果已到达当前数据源的末尾... if (index _suggestions.length) { // ...则一次性追加 10 条新数据 _suggestions.addAll(generateWordPairs().take(10)); } return _buildRow(_suggestions[index]); });这段代码包含两个值得反复品味的细节i.isOdd返回Divider()让每条单词对之间自动出现分隔线视觉上层次分明且避免了额外维护一个数据分隔线混合列表的成本。i ~/ 2整除运算由于每两条数据行之间夹着一条分隔线外部索引i与数据索引index满足index i ~/ 2。例如外部索引 0、2、4 分别对应数据索引 0、1、2。源码注释main.dart对此有清晰说明。3.3 数据追加无限增长的引擎触发无限的关键判断是if (index _suggestions.length) { _suggestions.addAll(generateWordPairs().take(10)); }其执行语义是当ListView.builder滚动到当前已生成数据的末尾、需要渲染下一条尚未存在的数据时立即调用english_words包提供的generateWordPairs()生成器通过.take(10)截取 10 个新的 WordPair 追加到_suggestions中。由于每次触底都会补充 10 条列表便获得了持续滚动的燃料从而表现为无限列表。注意这里并未调用setState——这是因为追加发生在itemBuilder同步构建流程内部追加后立即使用_suggestions[index]取出数据渲染数据源与渲染处于同一帧无需触发重建。从源码结构可以推断这里的每次 10 条是一个刻意选择的较小批量既保证触底追加的粒度足够细腻又避免一次性生成过多数据浪费内存是典型的懒加载数据供给节奏。四、列表项交互收藏与状态切换无限列表的每一行由_buildRow()渲染main.dartWidget _buildRow(WordPair pair) { final alreadySaved _saved.contains(pair); return ListTile( title: Text( pair.asPascalCase, style: _biggerFont, ), trailing: Icon( alreadySaved ? Icons.favorite : Icons.favorite_border, color: alreadySaved ? Colors.red : null, ), onTap: () { setState(() { if (alreadySaved) { _saved.remove(pair); } else { _saved.add(pair); } }); }, ); }数据展示pair.asPascalCase将随机生成的英文单词对转换为 PascalCase 格式如 pineappleJuice并以 18 号字体呈现收藏切换trailing图标根据_saved集合是否包含当前条目在实心红色心形Icons.favorite与空心灰色心形Icons.favorite_border之间切换状态管理点击行调用setState增删_saved触发 UI 刷新。这里的SetWordPair之所以能高效完成包含判断是因为WordPair类型提供了基于内容而非引用的相等性比较。五、收藏列表页Navigator 路由跳转AppBar 右侧的IconButton图标为Icons.list绑定_pushSaved()main.dart点击后通过Navigator.push与MaterialPageRoute跳转到一个独立的收藏页void _pushSaved() { Navigator.of(context).push( MaterialPageRoute( builder: (context) { final tiles _saved.map( (pair) ListTile( title: Text(pair.asPascalCase, style: _biggerFont), ), ); final divided ListTile.divideTiles( context: context, tiles: tiles, ).toList(); return Scaffold( appBar: AppBar(title: Text(Saved lists)), body: ListView(children: divided), ); }, ), ); }收藏页的构建同样体现了良好的工程习惯使用_saved.map(...)将收藏集合映射为ListTile列表并用ListTile.divideTiles()在相邻条目间自动插入分隔线该页面数据规模受用户主动收藏行为约束、通常较小因此这里退化为常规的ListView(children: ...)一次性构建与主列表的懒加载形成按数据规模选择合适的构建策略的对照示范整个导航使用MaterialPageRoute推入新路由保留了平台默认的页面转场动画与返回手势。六、应用入口与主题配置入口 main.dart 保持了一贯的简洁void main() runApp(MyApp()); class MyApp extends StatelessWidget { override Widget build(BuildContext context) { return MaterialApp( title: Infinite List, theme: ThemeData( primaryColor: Colors.blue, accentColor: Colors.lightBlue), home: RandomWords(), ); } }ThemeData定义了以蓝色为主色、浅蓝为强调色的 Material 主题home: RandomWords()直接将有状态组件RandomWords其状态类RandomWordsState承载全部列表逻辑作为首页未引入路由表结构清晰。七、源码证据与延伸学习关注点仓库路径说明无限列表全部业务逻辑infinite_list/lib/main.dartListView.builder懒加载、数据追加、收藏交互、路由跳转依赖声明infinite_list/pubspec.yamlenglish_words提供随机单词对数据源Android 构建配置infinite_list/android/app/build.gradle包名github.nisrulz.infinitelist、SDK 版本要求批量拉取依赖脚本get_packages.sh遍历仓库所有示例工程执行flutter packages get同类列表示例using_listview/lib/main.dart同仓库另一聚焦ListView的独立示例可对照学习延伸建议掌握本示例后可进一步探索 Flutter 列表性能优化的进阶主题——例如itemExtent固定条目高度时的滚动加速、ListView.separated原生分隔线构造器可替代本文的奇偶行技巧、ScrollController监听滚动位置做更精细的分页触发以及GridView.builder在网格布局中的懒加载用法。本示例的按需构建 触底追加范式是理解这些进阶能力的最佳起点。赞分享示例工程移动开发【免费下载链接】flutter-examples[Examples] Simple basic isolated apps, for budding flutter devs.项目地址https://gitcode.com/gh_mirrors/fl/flutter-examples点击查看免费下载相关推荐基于 react-infinite-scroll-component 实现滚动自动加载antd List 无限滚动示例infinite-load深度拆解基于 react infinite scroll component 实现滚动自动加载antd List 无限滚动示例infinite load深度拆解前端UI组件设计系统Ant Design List 无限滚动加载实战结合 react-infinite-scroll-component 实现滚动自动加载列表Ant Design List 无限滚动加载实战结合 react infinite scroll component 实现滚动自动加载列表 导读 本文聚焦 A前端UI组件设计系统Ant Design List 虚拟列表实战基于 rc-component/virtual-list 渲染无限长列表Ant Design List 虚拟列表实战基于 rc component/virtual list 渲染无限长列表 在数据量大、单条行高固定、滚动频繁的列前端UI组件设计系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

AI EASY获得2026京津冀算力算法大赛一等奖

AI EASY获得2026京津冀算力算法大赛一等奖

近日,京津冀算力算法大赛圆满落幕。AI EASY凭借在安全算法架构、算力资源利用效率、多模态风险识别、私有化部署与产业化应用方面的几大核心优势,获得评审团高度认可,荣获大赛一等奖。本次大赛聚焦算力优化、国产算力适配、产业赋能升级与场景…

2026/10/15 18:54:42 阅读更多 →
改造 MSF Meterpreter 提升稳定性:Viper 平台下的 CS Beacon 式实战方案

改造 MSF Meterpreter 提升稳定性:Viper 平台下的 CS Beacon 式实战方案

文档教程网络安全 【免费下载链接】Viper Adversary simulation and Red teaming platform with AI 项目地址: https://gitcode.com/gh_mirrors/vip/Viper 点击查看 免费下载 Meterpreter 与 Cobalt Strike Beacon 是红队模拟中最常用的两种后渗透工具,…

2026/10/15 18:54:42 阅读更多 →
C语言实现队列:环形队列与链式队列的完整实战

C语言实现队列:环形队列与链式队列的完整实战

队列(Queue)大概是数据结构里最贴近日常生活的模型:食堂打饭、银行叫号、外卖订单排队处理,全是同一套规则——先来的先办,后来的后等。但“懂规则”和“会实现”是两码事,尤其当你用C语言这种几乎没有封装…

2026/10/15 18:54:42 阅读更多 →

最新新闻

AI论文写作要点梳理与前沿研究成果应用实践指南

AI论文写作要点梳理与前沿研究成果应用实践指南

外文文献“白嫖”与高效阅读全攻略 宝子们,是不是一提到下载外文文献就头大? 想找的文献要么全网搜不到,要么下载流程复杂到让人原地爆炸。好不容易在某个小网站找到了资源,又担心版权问题不敢点,更别说有些平台动辄几…

2026/10/15 19:38:32 阅读更多 →
人脸识别开集测试:从闭集幻觉到真实拒识的工程实践

人脸识别开集测试:从闭集幻觉到真实拒识的工程实践

1. 开集与闭集测试:人脸识别系统落地前必须跨过的那道坎 我第一次在某高校实验室参与人脸识别项目验收时,被现场演示结果惊得愣在原地——模型在内部测试集上准确率高达99.2%,可当现场随机邀请三位未录入过人脸的访客走进识别区域&#xff0c…

2026/10/15 19:38:32 阅读更多 →
深耕支付宝收钱码推广领域,拓推客以专业合作服务赋能地推从业者

深耕支付宝收钱码推广领域,拓推客以专业合作服务赋能地推从业者

移动支付已深度融入日常消费与商业经营场景。线下商户对于便捷收款、数字化经营工具及相关支付服务的需求持续受到关注,与之相关的商户拓展和推广服务,也逐渐成为连接支付产品与线下经营场景的重要环节。在这一行业背景下,专业化、规范化的推…

2026/10/15 19:38:32 阅读更多 →
记忆系统演化:从简单缓存到多层认知架构

记忆系统演化:从简单缓存到多层认知架构

在大模型驱动的智能体(AI Agent)系统研发初期,绝大多数团队对“记忆”的理解仅仅停留在会话上下文的传递上。早期的 LangChain 会话记忆组件(如 ConversationBufferMemory 或 ConversationSummaryMemory)通过简单的字符…

2026/10/15 19:38:32 阅读更多 →
观测全景:基于 OpenInference 的可观测体系总结

观测全景:基于 OpenInference 的可观测体系总结

随着大语言模型(LLM)与多智能体(Multi-Agent System)系统从概念验证(POC)全面进入企业生产级核心业务,传统的微服务可观测性体系(Metrics、Logs、Traces)遭遇了前所未有的…

2026/10/15 19:38:32 阅读更多 →
OpenCV+Python轻量物体识别:纯CPU端到端方案

OpenCV+Python轻量物体识别:纯CPU端到端方案

简介:本资源是一套面向Python与OpenCV初学者及计算机视觉入门开发者的自定义物体识别实战教程,聚焦于零基础构建可识别任意目标的检测模型,适用于智能监控、工业质检、教学实验等场景。压缩包共709个文件,含663张标注用JPG图像、2…

2026/10/15 19:37:32 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 9:49:14 阅读更多 →