在LVGL(LittlevGL)中,事件冒泡是一个重要的概念,它允许事件从一个对象传递到其父对象,直到找到一个能够处理该事件的对象或者达到顶层对象。以下是如何在LVGL中实现和使用事件冒泡的概述:
事件冒泡的理解
- 当用户交互(如触摸屏点击)发生在一个对象上时,该对象首先接收到事件。
- 如果对象启用了事件冒泡标志(
LV_OBJ_FLAG_EVENT_BUBBLE
),并且没有处理该事件,事件会被传递给它的父对象。 - 如果父对象也启用了事件冒泡并且没有处理事件,事件将继续向上传递,直到找到处理该事件的对象或者达到顶层对象为止。
事件处理
- 每个对象可以注册一个或多个事件处理器来处理特定类型的事件,例如
LV_EVENT_CLICKED
,LV_EVENT_PRESSED
,LV_EVENT_RELEASED
等。 - 事件处理器会在事件发生时被调用。
使用到的API
- 设置事件冒泡:使用
lv_obj_add_flag()
函数为对象添加LV_OBJ_FLAG_EVENT_BUBBLE
标志来启用事件冒泡。 - 注册事件处理器:使用
lv_obj_add_event_cb()
或lv_obj_add_event_cb_filtered()
注册事件处理器。 - 获取事件信息:使用
lv_event_get_code()
,lv_event_get_target()
,lv_event_get_current_target()
,lv_event_get_param()
等函数。 - 阻止事件冒泡:在事件处理器中,通过返回
LV_RES_OK
或LV_RES_INHIBITED
来阻止事件继续向上冒泡。
实例
事件函数
1为按键1的事件点击后会处理并将事件传递给父控件的事件
2为按键2的事件函数点击后会触发事件并在函数中调用函数阻止冒泡
3为父控件的事件
//事件1
static void chlid_btn_event_cb(lv_event_t *e){lv_event_code_t code = lv_event_get_code(e);lv_obj_t * child_btn = lv_event_get_target(e);if(code == LV_EVENT_CLICKED) {LV_LOG_USER("zhi_geng_niao_01");/* 可以在这里添加更多的处理逻辑 */}
}
//事件2
static void chlid_btn_event_cb_2(lv_event_t *e){lv_event_code_t code = lv_event_get_code(e);lv_obj_t * child_btn = lv_event_get_target(e);if(code == LV_EVENT_CLICKED) {LV_LOG_USER("zhi_geng_niao_02");/* 可以在这里添加更多的处理逻辑 */lv_event_stop_bubbling(e);}
}
//事件3
static void parent_cont_event_cb(lv_event_t *e){lv_event_code_t code = lv_event_get_code(e);lv_obj_t * parent_cont = lv_event_get_target(e);if(code == LV_EVENT_CLICKED) {LV_LOG_USER("zhi_geng_niao_03");/* 可以在这里添加更多的处理逻辑 */}
}
控件代码
//显示
void lv_example_event_bubbling(void) {/* 创建一个屏幕 */lv_obj_t * scr = lv_scr_act();/* 创建一个父容器 */lv_obj_t * parent_cont = lv_obj_create(scr);lv_obj_set_size(parent_cont, 200, 200);lv_obj_center(parent_cont);lv_obj_add_flag(parent_cont, LV_OBJ_FLAG_EVENT_BUBBLE); /* 启用事件冒泡 */lv_obj_add_event_cb(parent_cont, parent_cont_event_cb, LV_EVENT_ALL, NULL); /* 注册事件处理函数 *//* 创建第一个子按钮 */lv_obj_t * child_btn1 = lv_btn_create(parent_cont);lv_obj_set_size(child_btn1, 100, 50);lv_obj_align(child_btn1, LV_ALIGN_TOP_MID, 0, 20);lv_obj_add_flag(child_btn1, LV_OBJ_FLAG_EVENT_BUBBLE); /* 启用事件冒泡 */lv_obj_add_event_cb(child_btn1, chlid_btn_event_cb, LV_EVENT_ALL, NULL); /* 注册事件处理函数 *//* 创建第二个子按钮 */lv_obj_t * child_btn2 = lv_btn_create(parent_cont);lv_obj_set_size(child_btn2, 100, 50);lv_obj_align(child_btn2, LV_ALIGN_BOTTOM_MID, 0, -20);lv_obj_add_flag(child_btn2, LV_OBJ_FLAG_EVENT_BUBBLE); /* 启用事件冒泡 */lv_obj_add_event_cb(child_btn2, chlid_btn_event_cb_2, LV_EVENT_ALL, NULL); /* 注册事件处理函数 */
}
总结
冒泡事件指的是子控件触发事件后完成事件,在调用父控件的事件。要不调用父控件必须在子控件中阻止其冒泡
阻止冒泡的函数时
lv_event_stop_bubbling(e);
效果图
运行结果
点击了父控件1下 03
按键1 01 03
按键2 02