LVGL 入门(十二):界面切换

LVGL 入门(十二):界面切换 目录一、前言二、界面切换核心逻辑三、方式一隐藏界面实现切换四、方式二删除界面实现切换五、删除法完整界面切换实现六、隐藏法优化方案七、总结八、结尾一、前言我是Hello_Embed在上一篇笔记中我们通过简易方式创建了两个独立界面但仅支持静态切换无法满足实际产品的交互需求。本篇将正式学习LVGL 动态界面切换核心逻辑分为隐藏界面和删除旧界面 显示新界面两种方案同时讲解两种方案的优缺点与优化方法帮你掌握嵌入式 GUI 多界面切换的基础实现。二、界面切换核心逻辑界面切换功能需要通过编码实现核心处理逻辑分为两种覆盖 / 隐藏优点是不会操作空指针代码更安全删除旧界面后显示新界面优点是节省硬件内存资源适合资源受限的嵌入式设备。我们新建两个代码文件来实现这两种界面切换方案。三、方式一隐藏界面实现切换通过隐藏父容器的方式实现界面的隐藏切换代码如下voidlesson6_1_demo(void){page_a();page_b();}staticvoidpage_a(void){lv_obj_t*page_contlv_button_create(lv_screen_active());lv_obj_set_size(page_cont,lv_pct(100),lv_pct(100));lv_obj_set_style_bg_color(page_cont,lv_color_hex(0x00ff00),0);lv_obj_t*btnlv_button_create(page_cont);lv_obj_align(btn,LV_ALIGN_CENTER,0,40);lv_obj_add_flag(btn,LV_OBJ_FLAG_CHECKABLE);lv_obj_set_height(btn,LV_SIZE_CONTENT);lv_obj_t*labellv_label_create(btn);lv_label_set_text(label,Page[a]);lv_obj_center(label);lv_obj_add_event_cb(btn,event_handler,LV_EVENT_ALL,label);}staticvoidpage_b(void){lv_obj_t*page_contlv_button_create(lv_screen_active());lv_obj_set_size(page_cont,lv_pct(100),lv_pct(100));lv_obj_set_style_bg_color(page_cont,lv_color_hex(0x00ff00),0);lv_obj_t*btnlv_button_create(page_cont);lv_obj_align(btn,LV_ALIGN_CENTER,0,40);lv_obj_add_flag(btn,LV_OBJ_FLAG_CHECKABLE);lv_obj_set_height(btn,LV_SIZE_CONTENT);lv_obj_t*labellv_label_create(btn);lv_label_set_text(label,Page[b]);lv_obj_center(label);lv_obj_add_event_cb(btn,event_handler,LV_EVENT_ALL,label);}staticvoidevent_handler(lv_event_t*e){lv_obj_t*btnlv_event_get_target(e);lv_event_code_tcodelv_event_get_code(e);lv_obj_t*labellv_event_get_user_data(e);lv_obj_t*page_contlv_obj_get_parent(btn);if(codeLV_EVENT_VALUE_CHANGED){LV_LOG_USER(%s,lv_label_get_text(label));lv_obj_add_flag(page_cont,LV_OBJ_FLAG_HIDDEN);}}代码逻辑先创建全屏容器page_cont设置颜色和大小在容器上创建按钮和标签绑定事件回调回调函数中按钮触发后隐藏当前界面的父容器完成界面隐藏切换。四、方式二删除界面实现切换删除界面会释放内存资源仅需修改回调函数中的核心代码//lv_obj_add_flag(page_cont, LV_OBJ_FLAG_HIDDEN);lv_obj_delete(page_cont);内存监控配置开启 LVGL 内存监控可直观观察内存变化补充开启系统监控宏定义#defineLV_USE_SYSMON1#defineLV_USE_PERF_MONITOR1#defineLV_USE_MEM_MONITOR1配置完成后重新编译运行即可查看性能与内存参数。使用删除界面的方式可观察到内存占用会随界面删除而减小。五、删除法完整界面切换实现结合删除逻辑实现删除旧界面 创建新界面的完整切换voidlesson6_1_demo(void){page_a();//page_b();}staticvoidevent_handler(lv_event_t*e){lv_obj_t*btnlv_event_get_target(e);lv_event_code_tcodelv_event_get_code(e);lv_obj_t*labellv_event_get_user_data(e);lv_obj_t*page_contlv_obj_get_parent(btn);if(codeLV_EVENT_VALUE_CHANGED){LV_LOG_USER(%s,lv_label_get_text(label));if(strcmp(lv_label_get_text(label),Page[a])0){page_b();}elseif(strcmp(lv_label_get_text(label),Page[b])0){page_a();}//lv_obj_add_flag(page_cont, LV_OBJ_FLAG_HIDDEN);lv_obj_delete(page_cont);}}实现逻辑在回调函数中判断当前界面触发后创建目标新界面同时删除旧界面也可创建两个独立回调函数分别对应界面 A、B 的切换逻辑。六、隐藏法优化方案单纯隐藏界面不会释放内存重复创建会导致内存占用持续增大最终引发程序崩溃。优化核心仅创建一次界面通过全局变量管理避免重复创建。staticlv_obj_t*g_pagea_cont;staticlv_obj_t*g_pageb_cont;staticvoidpage_a(void){g_pagea_contlv_button_create(lv_screen_active());lv_obj_set_size(g_pagea_cont,lv_pct(100),lv_pct(100));lv_obj_set_style_bg_color(g_pagea_cont,lv_color_hex(0x00ff00),0);lv_obj_t*btnlv_button_create(g_pagea_cont);lv_obj_align(btn,LV_ALIGN_CENTER,0,40);lv_obj_add_flag(btn,LV_OBJ_FLAG_CHECKABLE);lv_obj_set_height(btn,LV_SIZE_CONTENT);lv_obj_t*labellv_label_create(btn);lv_label_set_text(label,Page[a]);lv_obj_center(label);lv_obj_add_event_cb(btn,event_handler,LV_EVENT_ALL,label);}staticvoidpage_b(void){g_pageb_contlv_button_create(lv_screen_active());lv_obj_set_size(g_pageb_cont,lv_pct(100),lv_pct(100));lv_obj_set_style_bg_color(g_pageb_cont,lv_color_hex(0x00ff00),0);lv_obj_t*btnlv_button_create(g_pageb_cont);lv_obj_align(btn,LV_ALIGN_CENTER,0,40);lv_obj_add_flag(btn,LV_OBJ_FLAG_CHECKABLE);lv_obj_set_height(btn,LV_SIZE_CONTENT);lv_obj_t*labellv_label_create(btn);lv_label_set_text(label,Page[b]);lv_obj_center(label);lv_obj_add_event_cb(btn,event_handler,LV_EVENT_ALL,label);}staticvoidevent_handler(lv_event_t*e){lv_obj_t*btnlv_event_get_target(e);lv_event_code_tcodelv_event_get_code(e);lv_obj_t*labellv_event_get_user_data(e);lv_obj_t*page_contlv_obj_get_parent(btn);if(codeLV_EVENT_VALUE_CHANGED){LV_LOG_USER(%s,lv_label_get_text(label));//隐藏旧界面lv_obj_add_flag(page_cont,LV_OBJ_FLAG_HIDDEN);//显示新界面if(strcmp(lv_label_get_text(label),Page[a])0){lv_obj_remove_flag(g_pageb_cont,LV_OBJ_FLAG_HIDDEN);}elseif(strcmp(lv_label_get_text(label),Page[b])0){lv_obj_remove_flag(g_pagea_cont,LV_OBJ_FLAG_HIDDEN);}}}七、总结LVGL 界面切换有隐藏、删除重建两种核心方式隐藏法安全无空指针风险需全局变量避免重复创建删除法节省硬件内存适合嵌入式资源受限场景两种方案均可通过按钮事件实现无缝界面切换。八、结尾我们已经实现了基础的界面切换功能但实际开发中还需要协同处理 LVGL 定时器、动画在 RTOS 系统中更要协调多任务协作。我是Hello_Embed持续分享 LVGL 界面开发进阶技巧期待你的关注