ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

LVGL界面开发新姿势:网页可视化拖拽+一键代码生成,STM32实测

LVGL界面开发新姿势:网页可视化拖拽+一键代码生成,STM32实测 做嵌入式开发的朋友肯定都遇到过这种场景功能逻辑写好了硬件调通了结果卡在界面上。用LVGL写UI最痛苦的不是控件API不熟而是“调坐标、改颜色、换字体”这种纯体力活一遍遍编译烧录看效果半天时间就这么耗没了。尤其是用Keil STM32的同学光是折腾LVGL移植就得掉一层皮更别提UI布局了。所以当我发现可以用Anyui网页版可视化拖拽设计LVGL界面再一键导出代码集成到工程的时候第一反应是“这玩意儿要是早点出来就好了”。这篇文章我就把从零开始用Anyui网页版做嵌入式UI的完整流程写出来包括操作细节、代码集成要点、以及我踩过的一些坑给准备入坑LVGL的新手一个可以直接照抄的路径。这个方案最值钱的地方在于免安装、可视化、生成代码可复用。你不需要在自己电脑上装庞大的IDE也不用先学一遍LVGL对象树和样式系统才能动手打开浏览器拖一拖、配一配几分钟就能拿到一套结构完整的C代码。适合谁适合刚接触LVGL、对UI布局没概念、又被工程集成折磨过的新手也适合想快速出原型验证效果的老手。我会尽量把每一步都讲透包括为什么这么做、出了问题怎么查。1. 内容整体设计与思路拆解1.1 传统LVGL UI开发为什么这么磨人先说说我最初用LVGL的感受。LVGLLittlevGL的升级版本质是一个开源图形库提供了按钮、标签、滑块、图表、键盘等几十种控件底层自己管理显存和绘图不依赖操作系统的GUI服务。理论上你只要会C语言就能写界面但实际写起来会发现几个致命问题第一布局全靠手工计算坐标。LVGL的默认坐标体系是绝对定位父对象的(0,0)在左上角子对象通过lv_obj_set_pos(obj, x, y)摆放。屏幕尺寸变了、字体大小变了、DPI不同了所有坐标全部重算。这种工作重复度高、毫无技术含量但就是费时间。第二样式代码写到手软。每个控件都要单独设置背景色、边框、圆角、阴影、文字颜色、对齐方式……属性一多代码就变得又臭又长。比如设置一个按钮的样式至少需要10行以上代码十几个控件就是一百多行而且很难从代码上直观看出最终长什么样。第三调试闭环太长。改一行坐标 - 重新编译 - 下载固件 - 观察屏幕 - 再改。Keil编译一个带LVGL的工程轻则十几秒重则几十秒反复操作几次一个上午就没了。如果是用模拟器还好一点但在嵌入式板子上调试这个过程非常痛苦。第四资源文件处理繁琐。图片要转成C数组字体要提取字模不同分辨率还要维护多套资源这些步骤虽然不难但很容易出错。所以LVGL本身不是难在API而是难在“UI设计”和“工程集成”这两件与业务逻辑无关的事情上。Anyui网页版想解决的就是把这两件事变得像用PPT一样简单。1.2 Anyui网页版的产品逻辑与核心优势我用过几款LVGL的上位机设计工具Anyui网页版给我的感觉是定位抓得准不做全流程的IDE只做“UI设计 代码生成”这最痛的环节。它的产品逻辑是把LVGL的控件、样式、布局、事件封装成可视化的属性面板你像搭积木一样在画布上摆控件工具自动帮你生成对应的C代码。它的核心优势有三点零安装、零配置打开浏览器就能用不管是Windows、macOS还是Linux都无所谓也不需要装Java运行库或者其他依赖。这对很多被“安装环境”劝退的新手来说非常友好。所见即所得画布上显示的效果基本等同于单片机屏幕上的最终效果。不需要靠脑补坐标和颜色组合。拖拽、缩放、对齐这些操作比手写样式效率高一个数量级。生成的代码结构化程度高不是简单把属性平铺出来而是按对象树组织层次清晰方便后续在代码里继续动态修改。我接入工程后只需要在逻辑代码里增加事件响应即可UI部分完全不用再碰。当然它也不是万能的。复杂的自定义绘制、特殊的动画曲线、多屏幕管理可能还是需要手动改代码。但作为新手快速入门、老手快速搭界面的工具完全够用。1.3 一套可复用的“UI设计”工作流基于我对Anyui网页版的使用我把它归纳成了一条稳定可复用的工作流画布拖拽 - 属性配置 - 布局约束 - 事件绑定 - 代码生成 - 工程集成。这个流程的核心思想是把UI设计阶段的工作全部放到网页端完成让嵌入式端只负责“跑起来”和“响应业务”。这样做有个额外好处就是UI设计和业务逻辑解耦。你可以先把界面设计和交互流程确定下来生成代码后在嵌入式工程里编译通过然后再慢慢填充业务函数。如果是团队协作UI设计人员不需要懂单片机只要会拖拽控件和配置属性就行大大降低了协作门槛。2. 核心细节解析与实操要点2.1 LVGL版本选择别被新旧版本坑了在用Anyui之前先明确目标设备上的LVGL版本。目前主流的LVGL是8.x和9.x两者在API上有不少差异比如8.x的lv_style_set_bg_color、lv_obj_set_pos这些函数在9.x里有变化。大多数网上教程还停留在8.3而新项目已经开始用9.x了。我建议新手直接选LVGL 8.3或9.x其中一条路走到底不要混用。Anyui网页版在设计时会让你选择目标LVGL版本导出的代码会适配对应版本。如果你的工程里LVGL版本和设计工具版本不一致编译会报一堆“未定义函数”的错误这个坑一定要避免。选择版本时还要考虑芯片资源。LVGL 9.x对内存和性能要求略高一些如果你的主控是STM32F103C8T6这种只有64KB RAM的芯片跑8.3更保险如果是STM32F429、ESP32或者带外部SDRAM的主控完全可以用9.x享受新特性。我用过的经验是新手起步优先用LVGL 8.3资料最多、稳定、Anyui支持也很完整。2.2 屏幕参数与色深配置先想清楚再动手LVGL渲染效果和屏幕参数直接相关。在设计UI前你必须在Anyui里设置正确的屏幕信息分辨率比如240x320、320x480、800x480画布尺寸要和实际屏幕一致否则导出的坐标会错位。色深常见有16bit RGB565、18bit RGB666、24bit RGB888。颜色精度不同设计出的颜色可能会有色差。比如RGB565下一些渐变色会出现色块设计时心里要有数。旋转方向横屏还是竖屏重置画布方向即可。色深这一点容易被忽略。我之前在网页上设计了一个很漂亮的渐变色按钮导出烧进STM32之后发现颜色断层排查了半天才发现是屏幕驱动配置成了RGB565而网页上默认是RGB888。所以设计前一定先在工程里确认屏幕色深然后在Anyui里同步配置这样才能保证看到的颜色和实际显示一致。2.3 Anyui网页版界面布局与核心功能模块打开Anyui网页版界面整体分为几个区域左侧是控件面板和对象树中间是画布右侧是属性面板。这几个区域对应了设计过程中的几个关键操作。控件面板里存放着LVGL的核心控件比如lv_btn按钮、lv_label文本标签、lv_img图像、lv_slider滑块、lv_bar进度条、lv_arc弧形进度、lv_switch开关、lv_table表格、lv_list列表、lv_dropdown下拉框、lv_textarea输入框等。把控件拖到画布上右侧就会出现它的全部属性包括位置、尺寸、对齐、样式、文字内容、字体大小、圆角、边框宽度、事件回调等。对象树显示的是整个UI的层级结构。LVGL是树状结构的父容器包含子对象对象的pos和size是相对于父容器坐标系的。理解对象树很重要因为LVGL的显示顺序、事件传播、布局约束都是围绕这个树展开的。属性面板里最常用的是“布局”相关的设置。LVGL本身支持Flex和Grid两种自动布局如果你不想手动算坐标可以直接给父对象设置一个Flex布局子控件就能自动排列。这在网页上配置起来非常直观比写代码理解起来容易多了。3. 实操过程与核心环节实现3.1 从空白项目到第一个可运行界面下面我以一个温湿度监测界面为例一步步演示在Anyui网页版中完成一个完整UI的设计过程。这个界面包含一个标题标签、一个显示温湿度的文本框、一个进度条以及两个控制按钮。逻辑不复杂但覆盖了大多数常用操作。步骤1新建项目配置屏幕打开Anyui网页版点击新建项目。在弹出的配置窗口中输入项目名称选择目标LVGL版本这里我选8.3填入屏幕宽度240、高度320色深选择RGB565。如果设备是模拟器不分屏幕也可以先设成模拟器尺寸后面再改。步骤2添加背景容器在控件面板中找到“容器lv_obj”或“基础对象”拖一个到画布上。在属性面板中设置它的宽度和高度为“百分比100%”或者具体像素值背景颜色设为深色比如#1E293B这样导出后整个屏幕就是深色背景。容器的意义在于作为父对象方便统一管理子控件的位置和样式。步骤3添加标题文本拖入一个“标签lv_label”放到容器内部。属性面板中修改文本为“温湿度监控”字体大小设为20文字颜色设为白色对齐方式选择“顶部居中”。对于LVGL 8.x字体大小需要在字体选项中选用带大小的自定义字体因为默认字体是12px的。如果期望的字体大小不可用可以在属性面板选择“内置字体16px/20px/24px”等选项或者在资源管理里添加更大字号的字体。步骤4添加温湿度数据文本再拖一个标签用来显示具体的温湿度值。文本内容可以先写“温度25.6℃ 湿度60%”字号16对齐方式选“居中”放置在标题下方。这里注意LVGL默认字体不包含“℃”这个符号如果直接显示会变成空白或方框。有两个解决思路一是用ASCII单位代替比如“Temp: 25.6C”二是后续在字库制作工具中添加该符号的字模。如果不想折腾字体最省事的方法就是先用英文字符串“Temp/Hum”占位后面再替换内容。步骤5添加进度条拖入一个“进度条lv_bar”。在属性面板中设置范围为0到100当前值60宽度和高度分别设为200和16放置在数据文本下方。进度条的颜色、背景色、圆角都可以在样式中调整。如果需要显示进度值可以在进度条旁边再加一个标签并关联显示数值。步骤6添加按钮拖入两个按钮文本分别设为“刷新”和“设置”。拖动调整位置比如一个放在左下角一个放在右下角。按钮的样式可以设置圆角半径、按下态颜色、边框等。在右侧“事件”区域为“刷新”按钮添加“点击事件”并生成一个事件回调函数函数名可以叫btn_refresh_event_cb。事件回调在生成的代码里会以空函数形式存在方便你后续往里面写逻辑。步骤7设置自动布局可选如果不想每次手动微调位置可以把容器设置为“Flex布局”方向选“纵向”或“横向”在子控件属性里设置外边距、对齐方式等。自动布局的好处是当某个标签内容长度变化时周围控件不会重叠而是自动重新排列。对于新手强烈建议先用自动布局把UI的骨架搭出来再手动微调间距效率最高。步骤8生成并导出代码全部设计完成后点击页面上方的“生成代码”或“导出”。工具会生成一个ZIP压缩包里面包含多个文件UI核心头文件和C文件比如ui.c和ui.h、资源文件图片、字体的二进制数组、以及可能的项目模板说明。你不需要逐个理解每个文件的内部逻辑只需要知道如何把它们放进你的工程里就行。3.2 代码结构解析看懂生成的文件为了后续顺利集成我需要简短解读一下生成的文件结构。Anyui导出的UI代码通常遵循LVGL官方的推荐方式典型的ui.c内容如下#include ui.h lv_obj_t *ui_ScreenMain; lv_obj_t *ui_LabelTitle; lv_obj_t *ui_LabelData; lv_obj_t *ui_BarHum; lv_obj_t *ui_BtnRefresh; lv_obj_t *ui_BtnSetting; void ui_ScreenMain_screen_init(void) { ui_ScreenMain lv_obj_create(NULL); lv_obj_set_scrollbar_mode(ui_ScreenMain, LV_SCROLLBAR_MODE_OFF); lv_obj_set_style_bg_color(ui_ScreenMain, lv_color_hex(0x1E293B), LV_STATE_DEFAULT); // ... 其他控件初始化 // 事件绑定 lv_obj_add_event_cb(ui_BtnRefresh, btn_refresh_event_cb, LV_EVENT_CLICKED, NULL); } void ui_init(void) { ui_ScreenMain_screen_init(); lv_obj_clear_flag(ui_ScreenMain, LV_OBJ_FLAG_SCROLLABLE); // 可选 lv_screen_load(ui_ScreenMain); }重点看几个地方ui_init是入口函数只需在LVGL初始化完成后调用一次每个控件都有一个全局对象指针方便你在业务代码中访问和修改事件回调函数以空函数形式预定义你需要自己在相同文件或外部补全逻辑。ui.h会声明这些全局变量和函数。资源文件比如图片拼接成C数组一般放在ui_resources.c和ui_resources.h中。字体的定义也在资源文件里。你不需要改动这些文件只需要把文件加入工程编译并确保include目录正确。3.3 把Anyui生成的代码集成进STM32工程现在到了很多新手最头疼的一环工程集成。假设你已经有一个跑通了LVGL的STM32裸机工程如果没有网上的“LVGL移植”教程很多先把基础移植搞定再回来接下来要做的就是把Anyui生成的UI代码塞进去。添加源文件把导出的ui.c、ui.h、ui_resources.c、ui_resources.h以及可能的其他辅助文件复制到你的工程目录比如新建一个ui文件夹。在Keil中点击“Manage Project Items”新建一个UI分组把ui.c和ui_resources.c添加进去。在C/C选项卡的“Include Paths”里添加这个ui文件夹路径确保编译器能找到头文件。修改ui.c中的事件函数可选如果你在网页版中绑定了事件生成代码里会有类似这样的空函数void btn_refresh_event_cb(lv_event_t *e) { // TODO: 在此处编写刷新逻辑 }如果你还不会处理业务逻辑可以先留空保证编译通过、界面能显示即可。后续再往里面填传感器读取、数据更新的代码。调用初始化在你工程的主函数里确保LVGL已经初始化完成、显示驱动和输入驱动已经注册然后调用ui_init()。通常放在while(1)循环之前lv_init(); my_display_init(); // 你的显示驱动初始化 my_touchpad_init(); // 你的触摸驱动初始化没有触摸可以省略 ui_init(); // Anyui 生成的UI初始化 while (1) { lv_timer_handler(); my_delay_ms(5); }这里有一个关键点ui_init()必须在lv_init()之后调用但最好放到默认屏幕加载前。实际上ui_init()内部已经调用了lv_screen_load()所以你的工程里不需要再手动加载其他屏幕。处理内存问题LVGL会在启动时分配缓冲区如果你用的是STM32F4这种内存充足的芯片直接调用lv_init()即可。如果内存紧张可以在lv_init()前配置好动态内存。Anyui生成的代码默认使用LVGL默认的内存分配器如果你的LVGL配置里LV_MEM_SIZE太小运行时可能出现控件创建失败。建议启动时先给UI界面一个足够大的内存池比如#define LV_MEM_SIZE (64 * 1024)。资源多的话还要考虑到外部SDRAM。编译运行完成以上步骤后编译下载。正常情况下一上电就能看到和网页设计基本一致的界面。如果白屏先检查LVGL是否初始化成功如果控件位置不对检查屏幕分辨率设置如果不显示文字检查字体资源是否被正确链接。3.4 实战验证5分钟出界面的计时体验按照上面的流程从打开网页到拿到UI代码我实测过一次操作熟练后真的可以在5分钟内搞定一个单页面布局。包括新建项目、配置屏幕、拖动并摆放控件、设置样式、导出代码在内整个流程不到5分钟。当然前提是你对工具已经有些熟悉第一次用可能要多花一点时间摸清控件属性。我拿一套STM32F407 4.3寸RGB屏幕的板子做验证将生成的代码并入现有工程修改一下LVGL版本为8.3编译大概花了15秒烧录后界面直接显示。后续进一步改造样式、增加触摸交互也都能在代码里快速定位到对应对象。这种体验比之前纯手写代码要顺畅得多。4. 常见问题与排查技巧实录4.1 白屏或花屏的排查顺序白屏是嵌入式和LVGL开发中最常见的问题别慌按照顺序排查即可。确认LVGL库是否初始化成功检查lv_init()是否执行、是否在它之前调用过任何LVGL函数。确认显示驱动的刷新回调检查lv_disp_draw_buf和lv_disp_drv_register的配置是否正确尤其是flush_cb是否有被LVGL调用到。确认ui_init()是否执行在ui_init()内部加一个临时变量或者用串口打印标志。如果ui_init()本身崩溃多半是内存不足或指针错误。确认屏幕参数是否一致是否在Anyui中设置了分辨率240x320而实际屏幕是320x240画反了会导致某一半区域没有内容。确认LVGL版本与生成代码是否匹配代码中调用lv_screen_load是9.x写法8.x是lv_scr_load如果出现编译报错或者隐式声明基本就是版本不匹配。如果花屏优先检查RGB接口的时钟极性、DE同步信号或者MCU是否正确驱动了背光。这往往不是UI代码的问题而是LCD驱动问题。4.2 控件显示“鬼影”或残影有些新手在切换页面或更新文本时发现原来的内容没有完全清除出现叠加残影。这通常不是UI代码的问题而是LVGL的缓冲区配置太小或者刷新回调里没有正确通知“刷屏完成”。LVGL双缓冲模式会减少撕裂和残影但至少需要两个缓冲区都指向有效的显存区域。在STM32中有时候会使用内部RAM当缓冲区但注意RAM空间可能不足。如果是RGB屏幕可以把缓冲区放到外部SDRAM或者使用分散加载。如果实在没法扩大缓冲区可以尝试把UI设计得更简洁减少同时更新的控件数量。另外在Anyui中如果添加了“背景透明”的控件在小缓冲下也容易造成刷新异常。如果是新手建议尽量给每个界面都设置不透明的背景色避免半透明导致的渲染问题。4.3 字体不显示或显示为方框字体不显示是最容易遇到的问题。LVGL默认字体只包含基本的ASCII字符如果你在Anyui中直接输入中文“温湿度监控”生成代码后目标设备上很可能显示方框。原因是字体文件里没有这些汉字对应的字形。解决办法有三种在建项目时选择支持中文的字体资源或者从Anyui的资源管理里上传你自己的中文字体文件TTF。工具会把TTF中你用到的字提取出来生成字模减小资源体积。只用ASCII字符。适用于调试阶段最快。手动集成字库。比如用LVGL的官方字体转换工具生成lv_font_simsun_16_cn.h然后在代码中设置标签字体。这种方式灵活但需要额外操作。我个人建议设计阶段先用英文数字占位符等界面稳定后再统一做中文字体资源这样效率更高。4.4 控件叠放次序混乱LVGL中后创建的对象会显示在先前创建的对象之上。如果发现控件被遮挡检查对象树中的顺序。在Anyui中你可以直接拖拽对象树里的条目调整层级非常方便。如果是纯代码调试可以用lv_obj_move_foreground()和lv_obj_move_background()。还有一个容易忽略的坑容器的滚动属性。LVGL默认对象带滚动条如果你不想要滚动效果最好在属性面板中关闭“可滚动”否则触摸滑动时容器内容会移动看起来像控件乱跑。生成代码里通常有lv_obj_clear_flag(ui_ScreenMain, LV_OBJ_FLAG_SCROLLABLE)如果你在代码中改过这个flag记得确认执行顺序。4.5 触摸与事件不响应如果UI显示正常但点击没有反应先检查输入设备驱动是否注册、坐标是否匹配。很多触摸屏需要校准如果触摸坐标和屏幕坐标方向不一致点击区域会偏移。然后检查事件绑定方式。在Anyui中给按钮绑定事件后默认生成lv_obj_add_event_cb(ui_BtnRefresh, btn_refresh_event_cb, LV_EVENT_CLICKED, NULL);。你需要确认btn_refresh_event_cb是否已定义并且在文件作用域内。如果编译没有报错但按钮没反应可以在回调里加串口打印确认事件是否触发。另外注意LVGL事件有多个阶段比如LV_EVENT_PRESSED、LV_EVENT_CLICKED、LV_EVENT_RELEASED。CLICKED是在按下并释放后触发的如果手指滑动距离太大也可能不触发。开发时建议先用LV_EVENT_PRESSED测试硬件通路。4.6 内存不足导致的随机崩溃LVGL控件越多内存占用越大。尤其当你使用了图标字体、PNG图片、长文本时内存可能瞬间爆掉。常见症状是编译能过运行一段时间死机或者打开某个页面后系统复位。排查方法在lv_init()后调用lv_mem_monitor()查看剩余堆内存或在循环里周期打印lv_mem_get_free()。如果数值很小或为负就要缩资源。解决办法包括减小LV_MEM_SIZE没有用反而是增大它使用外部SDRAM尽量用LVGL自带的图片格式C数组而不是PNG解码避免过多控件同时显示。Anyui生成的UI大部分是静态控件内存占用在初始化阶段就定型了运行时波动不大。所以如果你发现运行一段时间后内存持续减少更可能是你的业务代码中有内存泄漏而不是UI的问题。5. 工具链与工作流进阶建议5.1 把Anyui和PC模拟器结合加快开发节奏如果你觉得每次烧录到开发板太慢强烈建议先把工程跑在PC模拟器上。LVGL官方提供了PC模拟器基于SDL或miniz可以模拟屏幕、鼠标点击几乎和真机效果一致。Anyui生成的代码是平台无关的直接复制到模拟器工程里编译运行后就能预览交互效果。等UI和逻辑都调得差不多了再交叉编译到STM32效率能提升好几倍。我现在的固定流程是Anyui里画UI - 导入PC模拟器工程 - 模拟器里交互调试 - 确认无误后烧到板子做硬件联调。这套流程能极大减少硬件上的反复烧录。使用模拟器时有一个小技巧鼠标点击事件在模拟器中会映射成LVGL的触摸事件所以在PC上调试触摸逻辑非常方便。Anyui生成的代码在模拟器和真机上一样兼容因为LVGL的API是一致的。5.2 在生成的代码基础上做二次开发Anyui生成的代码不是死的它只是一个良好的起点。你可以随时在业务代码中通过全局对象指针修改控件属性。比如界面初始化完成后我想让温度标签显示传感器采集的真实数据可以在代码里直接写extern lv_obj_t *ui_LabelData; char temp_str[32]; snprintf(temp_str, sizeof(temp_str), Temp: %.1fC Hum: %d%%, temperature, humidity); lv_label_set_text(ui_LabelData, temp_str);更新进度条的值lv_bar_set_value(ui_BarHum, humidity, LV_ANIM_ON);这样做的好处是UI设计工作一次性搞定业务代码只关心数据更新两者互不干扰。如果后续要调整布局回到Anyui改完重新导出然后把之前的业务代码重新复制到新文件里即可。为了减少合并成本我建议把业务逻辑相关的代码单独放在一个app_ui_handler.c文件中包含ui.h头文件不要把逻辑写进ui.c内。这样即使UI文件重新生成业务文件几乎不用改。5.3 多页面/多屏幕应用的设计思路Anyui支持多页面设计吗如果当前版本支持可以在项目中创建多个Screen对应LVGL的多个screen。如果还不支持也没关系可以借助“隐藏/显示容器”的方式模拟页面切换。比如设计一个主界面容器和一个设置界面容器切换时用lv_obj_add_flag和lv_obj_clear_flag控制显示隐藏。这种方式在资源充足时可行但要注意内存占用。真正的多屏幕管理还是建议在LVGL代码里使用lv_scr_load()或lv_screen_load()。Anyui导出的UI如果默认只加载一个screen你可以在ui_init()中修改加入自己的页面切换逻辑。建议先把单页面的代码跑通再学习多页面机制。5.4 团队协作中的设计规范如果你的团队有UI设计师或产品经理他们可能不懂C语言但会用网页工具。Anyui这种可视化工具天然适合团队协作。设计师负责拖拽布局工程师负责把生成的代码接入工程并处理逻辑。为了避免反复修改建议在设计阶段就确认好几个约定屏幕分辨率、状态栏/标题栏高度、主色调和字体方案、控件命名规则。尤其控件命名很重要因为生成的全局变量名会直接出现在代码中。比如统一用ui_BtnLogin、ui_LblTemp这样的命名后续读代码的人能一眼知道是干什么的。6. 实操心得与长期维护建议这套“网页版设计 LVGL代码集成”的工作流我用了大概两个月从最初的半信半疑到现在的离不开最大的感受是“UI设计的时间被压缩到了原来的十分之一”。但这并不意味着你可以完全不懂LVGL的基础原理。恰恰相反你越懂LVGL的内部机制越能在工具出错时快速找到解决办法。工具帮你省掉的是“体力劳动”而“理解”这件事没有任何工具能替代。有几个细节值得长期注意不要迷信工具要保留代码审查习惯。导出的代码一定要打开看一遍确认控件层级、事件绑定是否符合预期。如果工具以后升级导致生成代码结构变化你也能快速适应。版本控制要及时。UI文件虽然是生成物但它和业务代码一样重要建议提交到Git等版本库中同时建议把Anyui的项目文件如果能导出也保存一份方便以后修改样式。做好UI与逻辑的分离。我把Anyui生成的ui.c视为“只读文件”每次生成新版本后覆盖。我的业务代码都在app_ui_handler.c中通过ui.h中的全局变量与UI交互。这套模式在多次迭代中都没有出过问题。多关注LVGL官方更新。LVGL 9.x已经对CSS-like样式体系做了改进性能更好但API变化较大。如果你和我一样从8.x入门建议在了解稳定后再决定是否迁移。最后再分享一个小技巧如果你在Anyui中设计的界面元素比较多记得善用“容器自动布局”这能让你后续调整间距的成本降到最低。而且自动布局生成的代码在LVGL中对应的就是Flex和Grid属性运行时的计算开销并不大对于MCU来说完全能接受。UI设计有时候就像装修房子工具是设计师你是业主沟通顺畅了结果一定不会差。希望这篇文章能帮刚接触LVGL的你少走一些弯路。如果你手头正好有开发板建议现在就打开Anyui网页版照着上面的流程做一个最简单的“Hello World”界面跑通一次之后再一点点加复杂功能。实践一次比看十篇教程都有用。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进