1. 课程导入

在嵌入式图形界面开发中,当产品从“单屏演示”走向“可交付的整机 UI”时,页面数量会迅速增长:开机动画、主界面、设置页、参数编辑页、告警弹窗、数据曲线页、语言切换页等。若仍用“一个 Screen 打天下”的方式堆叠控件与逻辑,代码会变得难以维护,内存占用不可控,动画切换也容易出现卡顿与状态错乱。TouchGFX 的多页面架构设计,正是解决这一阶段问题的核心能力。

本课程围绕 TouchGFX Designer + MVP 模式 + Screen/View/Presenter 分层 + 页面切换与数据传递 展开,目标不是让你记住某个 API,而是建立一套可复用的多页面工程方法:能规划页面结构、能拆分视图与逻辑、能管理页面生命周期、能控制内存与刷新性能,并能在真实项目中定位“切页黑屏、返回丢状态、动画掉帧、内存溢出”等典型问题。

学习本课程后,你应当能够独立完成:
1)为一个中等复杂度的 HMI 产品设计页面拓扑与导航关系;
2)用 MVP 模式组织每个页面的 Model、View、Presenter;
3)实现页面跳转、返回、传参、弹窗与模态交互;
4)评估并优化多页面下的 RAM/Flash 占用与切换帧率;
5)建立可测试、可扩展、可多人协作的 TouchGFX 工程结构。

一、核心价值:为什么多页面架构决定项目成败

多页面架构的价值体现在三个层面。第一是可维护性:页面之间通过明确的导航接口通信,而不是互相直接操作控件,修改一个页面不会引发连锁崩溃。第二是资源可控性:TouchGFX 的每个 Screen 都会占用显存与控件对象内存,合理的页面创建/销毁策略能显著降低峰值 RAM。第三是交互体验:页面切换动画、转场效果、返回栈管理直接影响用户对产品“流畅度”的感知。

很多初学者误以为多页面就是“多建几个 Screen,然后 gotoScreen”。实际上,真正的架构设计要回答:页面何时创建、何时销毁、数据放在哪里、返回时如何恢复、动画期间是否允许输入。这些问题不解决,页面越多,工程越乱。

二、整体知识框架:从页面到架构的四层模型

下图给出本课程的整体知识框架。它把多页面架构拆成四个层次:页面层负责 Screen 与 View 的可视化;导航层负责跳转、返回栈与转场;逻辑层由 Presenter 承载业务交互;数据层由 Model 与共享数据池提供状态。四层之间通过接口解耦,形成可替换、可测试的结构。

TouchGFX 多页面架构四层模型 页面层 · 导航层 · 逻辑层 · 数据层 页面层(Screen / View) 开机页 · 主界面 · 设置页 · 参数编辑页 · 曲线页 · 告警弹窗 职责:控件布局、动画绑定、触摸事件采集、视觉状态呈现 导航层(Navigation / Transition) gotoScreen · 返回栈 · 转场动画 · 模态弹窗 · 页面参数传递 职责:页面生命周期调度、切换顺序控制、输入屏蔽与恢复 逻辑层(Presenter / Model) 业务规则 · 状态机 · 数据校验 · 异步任务 · 事件响应 职责:与硬件/协议解耦,通过接口驱动 View 更新 数据层(Shared Model / Data Pool) 全局配置 · 实时数据 · 用户设置 · 缓存与持久化接口 依赖方向:上层调用下层接口

三、方法流程:多页面工程的推进步骤

建议按以下流程推进一个多页面 TouchGFX 项目,避免“先画界面再补逻辑”的返工:

  1. 页面清单与拓扑设计:列出所有页面,标注入口、出口、是否模态、是否常驻,画出导航关系图。
  2. 数据归属划分:区分“页面私有状态”与“全局共享数据”,后者放入 Model 或数据池。
  3. MVP 骨架搭建:每个页面生成 View/Presenter,定义 Presenter 对外接口与 View 更新方法。
  4. 导航与转场实现:统一封装跳转函数,管理返回栈与动画时长。
  5. 生命周期与内存验证:测量页面创建/销毁时的 RAM 峰值,确认无泄漏。
  6. 性能与体验调优:检查切换帧率、触摸响应、动画与数据刷新是否冲突。

在代码层面,一个典型的页面跳转封装可能如下所示,注意它把“目标页面、参数、转场类型”统一收口,避免在业务代码里散落 goto 调用:

// Navigation.hpp
class Navigation {
public:
    static void goToMain();
    static void goToSettings();
    static void goToParamEdit(int paramId);
    static void goBack();
private:
    static ScreenStack stack;
};

// 使用示例
void SettingsPresenter::onSaveClicked() {
    Model::getInstance().saveConfig();
    Navigation::goBack();   // 统一返回,自动恢复上一页状态
}

四、案例场景:从单页到多页的典型演进

假设一个工业温控器 HMI,最初只有主界面显示温度与设定值。随着需求增加,需要加入:参数设置页、报警记录页、曲线查看页、语言选择页。若直接在主 Screen 上叠加隐藏容器,代码会迅速膨胀到数千行,且无法复用。

采用多页面架构后,主界面只负责总览与导航入口;设置页独立管理参数编辑与校验;曲线页独立处理数据采样与绘制;报警页独立维护列表滚动。页面之间通过 Model 共享温度数据,通过 Navigation 统一跳转。这样每个页面的 Presenter 可以单独进行单元测试,UI 设计师也能并行调整不同 Screen 的布局。

对比维度 单页面堆叠方案 多页面架构方案
代码组织 所有逻辑集中在一个 View,难以定位 按页面拆分 Presenter/View,职责清晰
内存峰值 所有控件常驻,RAM 占用高 按需创建/销毁,峰值可控
返回状态 需手动保存与恢复,易遗漏 返回栈 + Model 共享,恢复自然
动画体验 切换生硬,难以做转场 支持转场动画与模态弹窗
多人协作 冲突频繁,合并困难 页面级并行开发,冲突少

五、常见误区与复盘要点

误区一:页面越多越好。 每个 Screen 都有固定开销,过度拆分会导致切换频繁、内存碎片增加。应按“用户任务”划分页面,而非按控件数量。

误区二:在 View 里直接写业务逻辑。 这会让页面无法脱离硬件测试,也违背 MVP 初衷。业务判断应放在 Presenter 或 Model。

误区三:忽略页面生命周期。 在 Presenter 析构后仍触发回调,会导致野指针崩溃。务必在 deactivate 时注销定时器与异步回调。

误区四:返回时重新创建页面导致状态丢失。 应区分“销毁重建”与“缓存复用”,对高频返回页面采用缓存策略。
复盘时建议记录三项指标:页面切换平均耗时、峰值 RAM 占用、返回后状态一致率。它们能客观反映多页面架构是否健康,而不是仅凭“看起来流畅”判断。

六、学习路径建议

本课程后续将按“概念 → 骨架 → 导航 → 数据 → 性能 → 实战”推进。建议你按以下路径学习:先理解 MVP 与 Screen 生命周期,再动手搭建两个页面的跳转;随后加入返回栈与参数传递;接着引入共享 Model 与异步数据刷新;最后完成一个包含 5 个以上页面的综合案例,并进行内存与帧率优化。每学完一个模块,都应在自己的开发板上验证一次,避免只看不练。

多页面架构不是一次性设计出来的,而是在需求演进中不断重构的结果。掌握本课程的方法后,你面对的不再是“怎么让页面跳过去”,而是“如何让几十个页面在有限资源下稳定、流畅、可维护地协同工作”。这正是 TouchGFX 多页面架构设计的核心价值所在。