从 Demo 搭建的Flutter 演示项目 —— Forge

从入行以来就想着怎么积累点自己的东西,面试也好,自我实现也罢,日复一日的劳作终究不是自己期望的;于是面对一些解决的难题,或者觉得一些可用于基建的工程做了一些日常的记录;

forge 项目介绍

这个项目到底有什么意义?

在 vibe coding 火起来之前都是古法一行行写的,开始也不知道写什么就什么都做,后续接触了 vibe coding 就将多个小 demo 进行了整合;

最开始整理 Flutter Forge 时,题主并没有想清楚它最终会变成什么。只是觉得总得留下点东西;

直到真正把它们整合起来以后,才逐渐看到这个项目的价值。

作为一块长期保留的技术载体,后续再遇到新的 Flutter 能力、桌面端方案、平台插件、渲染问题或者架构思路,不需要再创建一个最终会被遗忘的 demo_test,而是可以把它放进已有体系中;对已经有一定经验的开发者来说,也提供了一些可以运行、修改和对比的工程案例,从一定程度上看这是有意义的,生活就是做有意义的事。

写了一堆 Flutter Demo 后,用 Vibe Coding 撸了一个项目

写了几年 Flutter,断断续续积累了不少 Demo。

有些是为了弄清楚一个概念:

  • Widget、Element 和 RenderObject 到底是什么关系?
  • 微任务与事件队列究竟谁先执行?
  • Isolate 能不能真正解决界面卡顿?
  • Overlay 为什么滚动以后会跟丢目标组件?

有些则来自真实项目:

  • Windows 和 macOS 如何统一文件选择能力?
  • Flutter 桌面端能不能实现复杂画布?
  • G-code 文件该如何解析并绘制路径解析?
  • Provider、Riverpod 和 Bloc 面对到底该怎么选?
  • 同一个功能到了不同平台,边界应该放在哪里?

当时觉得以后肯定用得上,半年后却很难想清楚背景

通过开始尝试 Vibe Coding 把这些散落在不同项目、不同目录里的实验,逐渐整理成了一个可以持续生长的 Flutter 项目------Flutter Forge ,可用于面向 macOS、Windows 和 Android 的 Flutter 机能学习

Vibe Coding 补上的,不只是代码

作面对十几个零散 Demo 整理是一个枯燥无味的工作,需要逐个阅读代码,确认插件依赖,迁移页面,补充路由,处理平台差异,再重新验证。

这个过程没有多少技术难度,却非常消耗耐心。而在 Vibe Coding 的协助下,题主可以先把目标、边界和已有代码交给 Agent,让它高效精准完成第一轮梳理:

  • 识别 Demo 分别属于什么主题;
  • 找出重复实现的公共能力;
  • 分析哪些代码可以直接迁移;
  • 判断哪些模块依赖特定平台;
  • 补齐模块入口、路由和基础说明;
  • 根据项目约束完成格式化、静态检查和测试。

题主负责决定项目应该长成什么样,Agent 负责消化大量上下文并完成机械性的迁移工作。两者结合以后,原本散落的 Demo 才逐渐形成了 Flutter Forge。

Agent 可以很快创建页面,却不会天然知道哪些目录允许修改;可以抽取公共组件,却未必知道这种抽象是否值得;也可以补充平台代码,但它不会自动理解对应哪些平台的能力支持,不清楚希望长期维护哪些平台。

Vibe Coding 的价值,不是替开发者做决定,而是降低繁重重复的工作使得开发者更多聚焦在创意工作上

一个能够运行的三端项目

Flutter Forge 当前主要围绕三个平台建设:

  • macOS;
  • Windows;
  • Android。

同时提供 Web 在线版本,方便读者不安装环境也能快速查看部分跨平台模块。这里需要强调一下:三端项目并不等于每个功能都必须在三个平台上保持完全一致。

像生命周期、事件循环、状态管理和普通动画这类纯 Flutter 能力,天然比较容易跨平台。但文件选择、USB 设备、桌面多窗口、视频播放、WebView 和 3D 渲染等能力,会受到操作系统与底层插件的影响。如果为了"全平台支持"这个标签,在每个平台上都勉强放一个无法正常使用的入口,反而会让项目越来越难维护。

所以 Flutter Forge 采用的是另一种思路:

统一的是项目入口和模块组织方式,不强行抹平平台本身的差异。

每个模块会声明自己支持的平台。支持当前平台时,用户可以正常进入;不支持时,模块仍然可以出现在学习目录中,但会明确标记为不可用,也不会注册成可以进入的路由。

这套机制本身并不复杂,却是这个项目从"Demo 合集"走向"多端工程"的关键一步。因为跨平台项目真正需要解决的,从来不是一段 Platform.isWindows,而是如何让平台差异只存在于明确、可管理的边界里。

"模块化"应该是什么

Flutter Forge 中目前已经整理了 20 多个学习模块。但题主不再想把它做成一个单纯展示 API 的项目。对于一个技术点,更希望它能够回答三个问题:

  1. 这个能力解决什么问题?
  2. 运行过程中究竟发生了什么?
  3. 放进真实项目时应该如何选择?

比如三棵树模块。如果只是写几段 Widget、Element 和 RenderObject 的定义,读者看完以后可能依然不知道它们之间是什么关系。所以这个模块会通过状态变化、生命周期日志和重绘区域,把抽象概念变成能够直接观察的运行过程。

再比如 Isolate。很多文章都会"耗时任务不要放在主 Isolate",但如果没有真正看到动画卡顿,很难建立直观认识。因此,项目里会把主线程计算和 Isolate 计算放在同一个页面中进行对比。当计算开始以后,界面是否掉帧、进度能否更新,结果会直接呈现在眼前。

状态管理模块也不只是分别放几个计数器,而是尝试把几种方案放到同一条演进路径中:

复制代码
setState → Provider → Riverpod → Bloc

题主更关心的不是它们的语法差异,而是随着业务复杂度上升:

  • 状态应该由谁持有;
  • Widget 如何获得状态;
  • 更新范围是否清晰;
  • 业务逻辑是否容易测试;
  • 原有方案会在什么地方开始变得吃力。

这些问题,才是状态管理真正需要解决的事情。

有些模块已经开始接近真实业务

随着内容不断增加,Flutter Forge 里也出现了一些不再像"简单 Demo"的模块。例如智能吸附线画板,需要处理元素创建、拖拽、坐标计算、对齐辅助线和快捷键。Overlay 跟随实验需要面对页面滚动、目标组件生命周期和浮层坐标转换。二维表格需要同时处理固定表头、固定行头和两个方向的滚动。

G-code 可视化则形成了一条更完整的数据链路:

flowchart LR A["选择 G-code 文件"] --> B["读取文件内容"] B --> C["解析 G-code 指令"] C --> D["生成刀路轨迹"] D --> E["Canvas 绘制轨迹"] E --> F["播放控制"] F --> G["同步高亮当前指令"]

正式项目通常不能随意试错,而实验可以用来验证作下一步决策:

  • 复杂交互应该放在哪一层;
  • 平台能力应该如何封装;
  • 一个实验方案距离真实业务还有多远;
  • 某个插件是否值得进入正式项目。

遇到新的渲染方案、桌面端插件或架构思路时,可以先在 Flutter Forge 基础上建立最小实验,观察它的真实表现,再决定是否带入业务项目。这比单纯阅读文档多了一层价值:它留下了可以重复运行的证据。

为了整合搭了一套 Workspace

当模块越来越多以后,把所有代码继续塞进同一个 lib 目录,很快又会回到最初的问题。因此,Flutter Forge 目前使用 Dart Workspace 管理主应用与本地能力包。

整体结构可以简单理解为:

markdown 复制代码
flutter_forge
├── apps
│   └── flutter_forge
└── packages
    ├── file_picker_bridge
    ├── flutter_ioc_core
    └── desktop_multi_window

主应用负责承载学习模块和统一入口。

file_picker_bridge 用于收敛文件选择的平台差异;flutter_ioc_core 用来实验依赖注入和对象作用域;desktop_multi_window则承载桌面多窗口相关能力。

主应用内部继续划分为四个主要边界:

vbnet 复制代码
app              应用启动、导航与窗口策略
module_registry  模块信息、路由与平台声明
shared           通用教学组件与共享边界
modules          可以独立理解和运行的学习模块

对一个学习项目来说,这套结构看起来可能有些重。但它解决的是一个很现实的问题:项目不能每增加一个 Demo,就把应用壳重新修改一遍。模块应该关心自己的页面、状态和领域逻辑;应用层只负责把模块组织起来;平台差异则尽量留在独立的能力包中。

从短期看,这比新建一个页面麻烦。从长期看,它让项目真正拥有了继续生长的可能。

Agent 写代码越快,项目边界反而越重要

Flutter Forge 还有一个比较特别的用途:它也是题主实验 Coding Agent 工程化工作流的地方。在使用 Agent 以前,项目文档主要写给人看。

开始让 Agent 参与开发以后,题主发现仅有一份 README 远远不够。Agent 能快速理解当前文件,却不一定知道整个项目的约束。它可能在错误的目录重新实现已有能力,也可能为了完成一个页面,引入不必要的依赖,甚至破坏其他平台。

因此,项目中逐渐增加了一组面向 Agent 的上下文文档,用来说明:

  • 当前项目有哪些模块;
  • 每一层允许依赖什么;
  • 修改某个模块前应该阅读哪些上下文;
  • 哪些共享能力已经存在;
  • 新增模块需要补充哪些元数据;
  • 哪些平台不能因为本次修改受到影响;
  • 完成任务后必须执行哪些验证。

除此之外,项目还加入了代码格式化、静态检查、单元测试、集成测试和质量门禁脚本。这些约束不是为了让 Agent 写出更多代码,恰恰是为了限制它不要随意写代码。

代码生成速度变快以后,真正稀缺的会变成清晰的边界、可靠的验证,以及开发的判断。

如果项目没有清晰结构,Agent 只会更快地制造混乱。但如果项目边界足够明确,它就能处理迁移、检索、补充测试和维护文档这些高消耗工作,让开发者把精力留给真正需要判断的部分。

写在最后

Flutter Forge 目前还不是一套完整课程,也不是所谓的"Flutter 最佳实践大全"。

有些早期模块仍然需要继续整理,部分平台能力也还在完善。macOS、Windows 和 Android 之间依然存在不少差异,Web 在线版本也不能覆盖所有原生能力。

但它至少让题主完成了一件过去一直没有做好的事情:

把那些写过、用过、验证过,却不知道应该放到哪里的代码,逐渐整理成了一个有上下文、能运行、可继续维护的项目。

Vibe Coding 并没有拔高这些 Demo 的意义,但它实实在在降低了整理和重构的门槛,让题主终于有机会重新审视过去的积累,并把它们连接起来。

如果你也写过很多 Demo 躺着吃灰却不知道应该如何整合;或者正在研究 Flutter 桌面端、多平台适配、状态管理、Isolate、Overlay、自定义绘制等问题,可以来 Flutter Forge 看看是否能带来一些启发。

不必急着再写一个新的,先试着把它们找回来组织起来。

项目还在持续更新,点个 Star 不一定能让代码跑得更快,但至少能证明:这些过往的 Demo,终于没有白写。

地址

在线预览:

Flutter Forge Web

项目地址:

lizy-coding/flutter_forge

仓库地址 lizy-coding/flutter_forge: 记录一些 Flutter 特性学习的 demo

相关推荐
m0_738185821 小时前
Flutter 鸿蒙化实战:flutter_background_service 适配 OpenHarmony,后台服务
flutter·华为·harmonyos·鸿蒙
事圆则缓2 小时前
Flutter 状态管理框架对比(一):先看地图,再选工具
前端·javascript·flutter
传奇开心果编程16 小时前
【Flutter入门练中学】第8课:动画与过渡
android·学习·flutter·ui·ios
传奇开心果编程18 小时前
【Flutter入门练中学】第11课:状态管理进阶与声明式路由
android·学习·flutter·ui·ios
陆断枫19 小时前
Flutter 列表性能优化
flutter
恋猫de小郭19 小时前
Flutter 多窗口重要优化合并,多窗口性能和实用性大幅提升
android·前端·flutter
gnip1 天前
Flutter 原生插件开发实战指南
前端·flutter
chenyin1 天前
Flutter 架构设计:Feature-First 与 Pub workspaces
flutter
潘锦1 天前
使用 Vibe Coding 的这6 种后遗症,你有吗?
cto·vibecoding