网罗开发 (小红书、快手、视频号同名)
大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验 。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索"展菲",即可纵览我在各大平台的知识足迹。
📣 公众号"Swift社区",每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友"fzhanfei",与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
背景介绍
AGUI 是 Espressif 基于 LVGL(Light and Versatile Graphics Library) 封装的 GUI 框架,主要用来在嵌入式屏幕上做图形化界面。
它能跑在 ESP32 / ESP32-S3 / ESP32-C3 等芯片上,并支持触控屏、字体、动画、布局、主题样式等一整套 UI 功能。
如果你来自 Web 或 App 前端背景,可以把 AGUI 理解成「运行在 MCU 上的轻量版 React + CSS」,界面描述是声明式的,逻辑也是事件驱动的。
项目结构规划
一个典型的 AGUI 项目结构如下:
css
/agui_project
├── main/
│ ├── main.c
│ ├── ui_main.c
│ ├── ui_main.h
│ └── event_handler.c
├── components/
│ └── agui_utils/ // 可选:自定义控件或封装
├── sdkconfig
├── CMakeLists.txt
└── partition.csv
在 ESP-IDF 项目中,AGUI 通常位于
/components/agui
目录下,由 Espressif 官方或第三方导入。
一个带按钮的前端页面
这是一个简单的「Hello AGUI」示例:
按下按钮,屏幕文字会发生变化。
c
#include "lvgl.h"
#include "esp_log.h"
#include "agui.h"
static const char *TAG = "AGUI_DEMO";
lv_obj_t *label;
// 按钮事件回调
static void btn_event_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED) {
lv_label_set_text(label, "你点我啦!");
ESP_LOGI(TAG, "Button clicked!");
}
}
void app_main(void)
{
// 初始化 AGUI
agui_init();
// 创建屏幕
lv_obj_t *scr = lv_scr_act();
// 创建标签
label = lv_label_create(scr);
lv_label_set_text(label, "Hello AGUI!");
lv_obj_align(label, LV_ALIGN_CENTER, 0, -40);
// 创建按钮
lv_obj_t *btn = lv_btn_create(scr);
lv_obj_align(btn, LV_ALIGN_CENTER, 0, 40);
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
lv_obj_t *btn_label = lv_label_create(btn);
lv_label_set_text(btn_label, "点我");
}
代码解析
agui_init()
:完成 LVGL 驱动初始化(屏幕、触控、时钟等)。lv_scr_act()
:获取当前活跃屏幕。lv_label_create()
/lv_btn_create()
:相当于创建 UI 组件。lv_obj_align()
:设置布局。lv_obj_add_event_cb()
:注册事件回调(相当于前端的onClick
)。
这个 Demo 完成了最基础的"前端交互"闭环:
界面展示 → 用户输入 → UI 状态变化。
构建多页面结构
AGUI/LVGL 支持多屏幕(Screen),可以用来模拟多页面前端:
c
lv_obj_t *screen_main;
lv_obj_t *screen_settings;
void create_main_screen(void) {
screen_main = lv_obj_create(NULL);
lv_obj_t *btn = lv_btn_create(screen_main);
lv_obj_t *label = lv_label_create(btn);
lv_label_set_text(label, "去设置页");
lv_obj_add_event_cb(btn, goto_settings, LV_EVENT_CLICKED, NULL);
}
void create_settings_screen(void) {
screen_settings = lv_obj_create(NULL);
lv_obj_t *label = lv_label_create(screen_settings);
lv_label_set_text(label, "设置页面");
}
static void goto_settings(lv_event_t *e) {
lv_scr_load(screen_settings);
}
void app_main(void) {
agui_init();
create_main_screen();
create_settings_screen();
lv_scr_load(screen_main);
}
这就像在 Web 前端中写了一个简单的 "Router + 页面跳转" 逻辑。
样式与动画
AGUI 支持类似 CSS 的样式系统:
c
lv_style_t style_btn;
lv_style_init(&style_btn);
lv_style_set_bg_color(&style_btn, lv_color_hex(0x4CAF50));
lv_style_set_radius(&style_btn, 10);
lv_obj_add_style(btn, &style_btn, 0);
还可以添加动画:
c
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, btn);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_time(&a, 1000);
lv_anim_set_exec_cb(&a, (lv_anim_exec_xcb_t)lv_obj_set_x);
lv_anim_start(&a);
这在嵌入式设备上能带来非常灵动的 UI 体验(比如呼吸动画、滑入效果、状态切换等)。
实际场景应用示例
假设你在做一个 智能家居中控屏,典型页面结构如下:
页面 | 功能 |
---|---|
首页 | 显示温湿度、WiFi 状态、时间 |
控制页 | 灯光 / 空调开关控制 |
设置页 | WiFi 配置、屏幕亮度调节 |
可以通过 AGUI 实现:
c
void show_home_screen(void);
void show_control_screen(void);
void show_settings_screen(void);
// 全局上下文
typedef enum { PAGE_HOME, PAGE_CONTROL, PAGE_SETTINGS } PageType;
PageType current_page;
// 页面切换逻辑
void switch_page(PageType target) {
switch(target) {
case PAGE_HOME:
show_home_screen();
break;
case PAGE_CONTROL:
show_control_screen();
break;
case PAGE_SETTINGS:
show_settings_screen();
break;
}
}
你可以把它理解为在 MCU 上"模拟 SPA(单页应用)"。
性能与注意事项
-
刷新率与内存
- ESP32 普通 SPI 屏幕一般能做到 20--30 FPS;
- 使用
DMA
+双缓存
可提升体验; - 注意减少大面积重绘。
-
异步与任务
- 尽量不要在事件回调里做阻塞操作;
- 复杂逻辑建议放到
FreeRTOS Task
中执行,然后再通过事件更新 UI。
-
调试技巧
- 使用
lv_log_register_print_cb()
捕获日志; - 使用
LV_USE_DEBUG
打开对象检查器; - 可以通过 UART/USB 把日志打印到上位机。
- 使用
总结
AGUI 完全可以支撑一个完整的嵌入式前端项目,从界面构建、事件交互、动画到页面管理,都能做到「像前端一样写 UI」。
它的核心优势是:
- 轻量高效(适合 ESP32 级别设备)
- 声明式开发体验
- 跨屏幕、跨交互统一框架
- 可定制控件丰富
而它的劣势也很明显:
- 没有浏览器那样的 CSS 布局调试;
- 内存、性能上要自己控制;
- 多线程和 UI 更新要谨慎管理。