大多数嵌入式 UI 项目出问题,并不是因为图形库。 项目变慢、变贵,往往发生在设计与固件之间:分辨率画错的设计稿、只能靠猜的字号、直接调用驱动的按钮回调函数。
我在 LVGL 带领解决方案工程团队,负责把客户的 UI 从 Figma 文件做成可量产的产品。 经历了各种项目之后,我发现顺利的项目和不顺利的项目之间,差别很少在于图形库, 而在于早期做出的几个决定,通常是在任何人写下第一行 UI 代码之前。
本文分享其中五个决定。它们最初以系列建议的形式发布在我的 LinkedIn 上,现在汇总到这里。
1. 从像素级精确的设计开始#
像素级精确的设计与物理显示屏完全一致。 屏幕尺寸、组件尺寸、图标大小、每个元素的 x 和 y 坐标以及字号,都对应目标屏幕上的真实像素。 如果显示屏是 640x480,Figma 画框就是 640x480。

无论你使用 LVGL、Qt 还是其他框架,总有人要把设计转换成代码。 设计做到像素级精确,定位元素和还原组件就只需要从设计稿上读取数值。 没有人需要猜测位置、凭肉眼缩放字体,或者去问设计师三个略有不同的内边距到底该用哪一个。
所以作为嵌入式 UI 开发者,无论设计来自专职设计师还是你自己,都要确保它是像素级精确的。 这是让设计到代码、再到真实显示屏的过程不出意外的最低成本方式。
2. 条件允许时,聘请专业的 UI/UX 设计师#
这是我在真实产品中多次看到带来巨大差别的一点。
嵌入式 UI 不只是在屏幕上摆放控件。 好的设计师会带来结构、视觉层次和一致性,而把设计当作事后补充时,这些很难做到。 他们会考虑间距、排版、对比度、色彩、对齐和平衡,也会考虑界面如何体现公司品牌。 色彩、字体、图标和 logo 的使用往往要遵循品牌规范,而当重点放在“先让功能跑起来”时,这些很容易被忽略。
这些细节决定了产品是否易读、易用,以及它给人的高级感。
硬件完全相同的两款产品,仅凭 UI 就可能给人截然不同的印象。
这对工程也有好处。 定义清晰的组件、一致的样式和明确的设计规则,意味着实现时更少猜测。 这会带来更少的迭代、更少的后期 UI 修改,以及更整洁的代码库。 在预算和范围允许时,设计师不是奢侈品,而是对产品的投资。
3. 没有设计师时,学会像设计师一样思考#
有时无法聘请设计师,嵌入式开发者就要同时负责实现和设计决策。
提升的最好方法是观察。 仔细看看你已经在用的产品:家用电器、汽车仪表盘、工业面板、手机应用和网站。 留意间距、字号、对比度、对齐、色彩、过渡动画,以及信息如何分组和排列优先级。
一个实用的练习是:挑选其他产品中设计出色的界面,用 LVGL 把它复刻出来。 这能锻炼你对布局、比例和层次的眼光,同时让你更快地把设计转换成代码。
还值得把 Figma 学到能在开始实现之前画出简单布局的程度。 即使是基础的设计,也能明确间距、字号和组件结构,并为你提供第 1 条建议中的像素级精确参考。
4. 用 Subject 将 UI 与固件逻辑解耦#
在许多项目中,UI 代码和固件逻辑最终紧密耦合在一起。 按钮回调函数会改变硬件状态、写全局变量、调用驱动,甚至直接在 UI 层处理网络请求和通信协议。 这在原型阶段可行,但随着产品发展,维护会越来越痛苦。
LVGL 的 subject 和 observer 把 UI 显示什么与应用如何工作分离开来。 UI 绑定到代表应用数据的 subject。 数据变化时,UI 自动更新。 用户与 UI 交互时,subject 发生变化,系统的其他部分随之响应。
下面是一个小例子:
static lv_subject_t temp_setpoint;
void ui_init(void)
{
lv_subject_init_int(&temp_setpoint, 21);
/* UI 侧:控件绑定到 subject,这里没有任何固件调用 */
lv_obj_t * slider = lv_slider_create(lv_screen_active());
lv_slider_bind_value(slider, &temp_setpoint);
lv_obj_t * label = lv_label_create(lv_screen_active());
lv_label_bind_text(label, &temp_setpoint, "%d °C");
}
/* 固件侧:响应 subject 的变化,对控件一无所知 */
static void setpoint_changed(lv_observer_t * observer, lv_subject_t * subject)
{
thermostat_set_target(lv_subject_get_int(subject));
}
void app_init(void)
{
lv_subject_add_observer(&temp_setpoint, setpoint_changed, NULL);
}c滑块和标签从不调用温控器驱动,驱动也从不接触任何控件。 这让集成 API、通信协议栈和后台任务变得更简单,而且无需硬件驱动或网络就能单独测试 UI。
LVGL Pro UI 编辑器大量使用了 LVGL 的 subject 和 observer,让 UI 的测试和评审轻松许多。

关于 LVGL 的 subject 和 observer 的更多细节,请查看官方文档。
5. 使用框架的官方 UI 编辑器#
无论选择哪个框架,通常都值得学习厂商的官方编辑器。 它由开发框架的同一个团队打造,因此遵循预期的工作流程,并按功能的设计初衷提供支持。 实际效果就是开发更快、集成问题更少、UI 结构更一致。
对 LVGL 来说,这就是 LVGL Pro 编辑器。 UI 可以实时预览,无需重新编译,也无需搭建构建环境。 它鼓励基于组件、可复用元素的开发方式,能很好地扩展到多个屏幕和项目。 图片和字体会自动转换,因此没有手动转换步骤,也不用维护转换脚本。 XML 比等效的 C 代码更易读,准备发布时,编辑器会导出纯 C 代码。
你还可以通过在线查看器分享 UI, 让设计师、产品经理或客户在浏览器中打开并点击体验,无需任何开发环境。
使用官方工具并非强制,但它往往是提升嵌入式 UI 项目效率和一致性最有效的方法之一。
总结#
这些建议都与巧妙的代码无关。 它们的目的是让从想法到屏幕的过程短而可预期: 与硬件匹配的设计、对外观负责的人、UI 与固件可以独立变化的架构,以及省去手动步骤的工具。
如果你希望在自己的产品中落实这些做法, 我们的解决方案工程团队正是做这类工作的。 如果你也有自己的建议,欢迎在 LVGL 论坛上分享。 我们很想听听。


