我们在实际使用 LVGL 完成一些项目时,通常需要展示不止一个页面,此时这些页面要如何更好的进行管理成为了一个需要解决的问题,如果处理不当,在资源短缺的嵌入式设备中很可能会因为过多页面的加载但却没有及时释放造成系统的崩溃。
现在就为大家展示一下我所构建的页面管理框架,如果设计上有存在什么问题,欢迎留言讨论。
1、前期准备
在开始之前需要了解一下几个核心函数。
/* 屏幕(页面)是没有父对象的特殊对象。所以它们可以像这样创建 */lv_obj_t*page =lv_obj_create(NULL);/* 加载想要显示的屏幕(页面) */lv_scr_load(page);/* 删除对象的所有子项(但不是对象本身) */lv_obj_clean(page);/* 动画加载屏幕(页面)
transition_type:LV_SCR_LOAD_ANIM_NONE:在 delay 毫秒后立即切换
LV_SCR_LOAD_ANIM_OVER_LEFT/RIGHT/TOP/BOTTOM:将新屏幕移动到当前的指定方向
LV_SCR_LOAD_ANIM_MOVE_LEFT/RIGHT/TOP/BOTTOM:将当前屏幕和新屏幕都向给定方向移动
LV_SCR_LOAD_ANIM_FADE_ON:在旧屏幕上淡出新屏幕 */lv_scr_load_anim(page, transition_type, time, delay, false);
2、页面管理结构体(struct page)
structpage{char name[32];// 页面名int page_level;// 页面等级,依靠这个来实现对上一页面的切换,该值越小,等级越高lv_obj_t*body_obj;// 页面结构体void*private_data;// 私有数据void(*onInit)(structpage*page);// 创建页面函数void(*onExit)(structpage*old_page,structpage*new_page);// 销毁页面函数};
3、其他相关变量
staticstructpage page_admin[10];// 存储所有创建好的页面staticint page_num =0;// 记录 page_admin[] 数组中存在多少个页面structpage*cur_page;// 记录当前显示的页面
4、页面管理相关函数
/* 设计页面的样式 */voidstyle_init(void){lv_style_init(&page_style);lv_style_set_bg_color(&page_style,lv_color_hex(0x000000));lv_style_set_radius(&page_style,0);lv_style_set_pad_all(&page_style,0);lv_style_set_border_side(&page_style, LV_BORDER_SIDE_NONE);}/* 创建一个指定样式的空白屏幕 */lv_obj_t*create_new_screen(void){lv_obj_t*main_obj =lv_obj_create(NULL);lv_obj_clean(main_obj);lv_obj_set_size(main_obj,240,240);// 根据个人屏幕大小修改lv_obj_add_style(main_obj,&page_style,0);return main_obj;}/* 初始化所有的页面 */voidall_page_init(void){style_init();// 主页面strcpy(page_admin[page_num++].name,"main_page");
page_admin[page_num -1].body_obj =create_new_screen();
page_admin[page_num -1].page_level =0;
page_admin[page_num -1].onInit = main_page_init;
page_admin[page_num -1].onExit = main_page_exit;
cur_page =&page_admin[page_num -1];lv_scr_load(page_admin[page_num -1].body_obj);// 设置该页面为第一个显示在屏幕上面的页面// 菜单页面strcpy(page_admin[page_num++].name,"menu_page");
page_admin[page_num -1].body_obj =create_new_screen();
page_admin[page_num -1].page_level =1;
page_admin[page_num -1].onInit = menu_page_init;
page_admin[page_num -1].onExit = menu_page_exit;// 默认展示主页面
cur_page->onInit(cur_page);}staticstructpage*page_search(char*name){for(int i =0; i < page_num; i++){if(strcmp(page_admin[i].name, name)==0)return&page_admin[i];}returnNULL;}/**
* @brief 页面切换函数
*
* @param new_page_name 新页面名
* @return 0 成功 -1 新页面不存在
*/intpage_transition(char*new_page_name){
Serial.printf("transition page = %s\n", new_page_name);if(strcmp(new_page_name,"")==0|| new_page_name ==NULL)return-1;structpage*new_page =page_search(new_page_name);if(new_page !=NULL){
cur_page->onExit(cur_page, new_page);
new_page->onInit(new_page);
cur_page = new_page;return0;}else{return-1;}}/**
* @brief 返回上一页面
*
* @param page 当前页面
* @return struct page 指针 上一页面 NULL 失败
*/structpage*return_prev_page(structpage*page){if(page ==NULL)returnNULL;int cur_page_level = page->page_level;for(int i = page_num -1; i >=0; i--){if(page_admin[i].page_level < cur_page_level){return&page_admin[i];}}returnNULL;}
5、实际例子
staticvoidevent_btn1_handler(lv_event_t* e){lv_event_code_t code =lv_event_get_code(e);//获取回调事件if(code == LV_EVENT_CLICKED){//点击事件structpage*new_page =&page_admin[1];
cur_page->onExit(cur_page, new_page);
new_page->onInit(new_page);
cur_page = new_page;}}staticvoidevent_btn2_handler(lv_event_t* e){lv_event_code_t code =lv_event_get_code(e);//获取回调事件if(code == LV_EVENT_CLICKED){//点击事件structpage*new_page =&page_admin[0];
cur_page->onExit(cur_page, new_page);
new_page->onInit(new_page);
cur_page = new_page;}}voidmain_page_init(structpage*page){lv_obj_t*body_obj = page->body_obj;lv_obj_t*block_obj =lv_obj_create(body_obj);lv_obj_set_style_bg_color(block_obj,lv_color_hex(0xafafaf), LV_STATE_DEFAULT);lv_obj_set_align(block_obj, LV_ALIGN_CENTER);lv_obj_set_size(block_obj,50,50);lv_obj_t* btn1 =lv_btn_create(body_obj);/*创建btn1*/lv_obj_add_event_cb(btn1, event_btn1_handler, LV_EVENT_ALL,NULL);/*设置btn1回调函数*/lv_obj_set_pos(btn1,20,40);lv_obj_t* label =lv_label_create(btn1);/*btn1内创建label*/lv_label_set_text(label,"jump button");}voidmain_page_exit(structpage*old_page,structpage*new_page){lv_obj_clean(old_page->body_obj);lv_scr_load_anim(new_page->body_obj, LV_SCR_LOAD_ANIM_MOVE_TOP,500,0, false);}voidmenu_page_init(structpage*page){lv_obj_t*body_obj = page->body_obj;lv_obj_t*block_obj =lv_obj_create(body_obj);lv_obj_set_style_bg_color(block_obj,lv_color_hex(0xffe604), LV_STATE_DEFAULT);lv_obj_set_align(block_obj, LV_ALIGN_CENTER);lv_obj_set_size(block_obj,50,50);lv_obj_t* btn1 =lv_btn_create(body_obj);/*创建btn1*/lv_obj_add_event_cb(btn1, event_btn2_handler, LV_EVENT_ALL,NULL);/*设置btn1回调函数*/lv_obj_set_pos(btn1,20,40);lv_obj_t* label =lv_label_create(btn1);/*btn1内创建label*/lv_label_set_text(label,"jump button");}voidmenu_page_exit(structpage*old_page,structpage*new_page){lv_obj_clean(old_page->body_obj);lv_scr_load_anim(new_page->body_obj, LV_SCR_LOAD_ANIM_MOVE_BOTTOM,500,0, false);}
版权归原作者 谢老板不用蟹 所有, 如有侵权,请联系我们删除。