一、前言
这节进行事件的总结,通过事件回调方式将用户和ui的交互行为绑定组合起来。
二、事件示例
1、示例1(点击事件)
#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_SWITCHstatic void event_cb(lv_event_t * e)
{LV_LOG_USER("Clicked");static uint32_t cnt = 1;lv_obj_t * btn = lv_event_get_target(e);lv_obj_t * label = lv_obj_get_child(btn, 0);lv_label_set_text_fmt(label, "%"LV_PRIu32, cnt);cnt++;
}/*** 为按钮添加点击事件*/
void lv_example_event_1(void)
{lv_obj_t * btn = lv_button_create(lv_screen_active());lv_obj_set_size(btn, 100, 50);lv_obj_center(btn);lv_obj_add_event_cb(btn, event_cb, LV_EVENT_CLICKED, NULL);lv_obj_t * label = lv_label_create(btn);lv_label_set_text(label, "Click me!");lv_obj_center(label);
}#endif
展示:为按钮添加点击事件,当用户点击时触发事件回调,在其中修改按钮的label的内容,通过全局变量点击一次则叠加一次该值。
2、示例2(处理多个事件)
#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_SWITCHstatic void event_cb(lv_event_t * e)
{lv_event_code_t code = lv_event_get_code(e);lv_obj_t * label = lv_event_get_user_data(e);switch(code) {case LV_EVENT_PRESSED:lv_label_set_text(label, "The last button event:\nLV_EVENT_PRESSED");break;case LV_EVENT_CLICKED:lv_label_set_text(label, "The last button event:\nLV_EVENT_CLICKED");break;case LV_EVENT_LONG_PRESSED:lv_label_set_text(label, "The last button event:\nLV_EVENT_LONG_PRESSED");break;case LV_EVENT_LONG_PRESSED_REPEAT:lv_label_set_text(label, "The last button event:\nLV_EVENT_LONG_PRESSED_REPEAT");break;default:break;}
}/*** 处理多个事件*/
void lv_example_event_2(void)
{lv_obj_t * btn = lv_button_create(lv_screen_active());lv_obj_set_size(btn, 100, 50);lv_obj_center(btn);lv_obj_t * btn_label = lv_label_create(btn);lv_label_set_text(btn_label, "Click me!");lv_obj_center(btn_label);lv_obj_t * info_label = lv_label_create(lv_screen_active());lv_label_set_text(info_label, "The last button event:\nNone");lv_obj_add_event_cb(btn, event_cb, LV_EVENT_ALL, info_label);
}#endif
展示:处理多个事件,包括按钮的点击、按下、长按、重复长按事件的处理。
3、示例3(冒泡事件)
#include "../lv_examples.h"
#if LV_BUILD_EXAMPLES && LV_USE_FLEXstatic void event_cb(lv_event_t * e)
{/*事件的最初目标。可以是按钮或容器*/lv_obj_t * target = lv_event_get_target(e);/*当前目标始终是向其中添加事件的容器*/lv_obj_t * cont = lv_event_get_current_target(e);/*如果单击容器,则不执行任何操作*/if(target == cont) return;/*将点击的按钮设为红色*/lv_obj_set_style_bg_color(target, lv_palette_main(LV_PALETTE_RED), 0);
}/*** 演示事件冒泡*/
void lv_example_event_3(void)
{lv_obj_t * cont = lv_obj_create(lv_screen_active());lv_obj_set_size(cont, 290, 200);lv_obj_center(cont);lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);uint32_t i;for(i = 0; i < 30; i++) {lv_obj_t * btn = lv_button_create(cont);lv_obj_set_size(btn, 70, 50);lv_obj_add_flag(btn, LV_OBJ_FLAG_EVENT_BUBBLE);lv_obj_t * label = lv_label_create(btn);lv_label_set_text_fmt(label, "%"LV_PRIu32, i);lv_obj_center(label);}lv_obj_add_event_cb(cont, event_cb, LV_EVENT_CLICKED, NULL);
}#endif
展示:事件冒泡(和js的冒泡事件类似,就是事件包含夫和子,比如例子中的容器和按钮,这里容器点击时事件不做处理,按钮事件则变为红色)
4、示例4(draw绘制事件)
#include "../lv_examples.h"#if LV_BUILD_EXAMPLESstatic uint32_t size = 0;
static bool size_dec = false;static void timer_cb(lv_timer_t * timer)
{lv_obj_invalidate(timer->user_data);if(size_dec) size--;else size++;if(size == 50) size_dec = true;else if(size == 0) size_dec = false;
}static void event_cb(lv_event_t * e)
{lv_obj_t * obj = lv_event_get_target(e);lv_draw_task_t * draw_task = lv_event_get_draw_task(e);lv_draw_dsc_base_t * base_dsc = draw_task->draw_dsc;if(base_dsc->part == LV_PART_MAIN) {lv_draw_rect_dsc_t draw_dsc;lv_draw_rect_dsc_init(&draw_dsc);draw_dsc.bg_color = lv_color_hex(0xffaaaa);draw_dsc.radius = LV_RADIUS_CIRCLE;draw_dsc.border_color = lv_color_hex(0xff5555);draw_dsc.border_width = 2;draw_dsc.outline_color = lv_color_hex(0xff0000);draw_dsc.outline_pad = 3;draw_dsc.outline_width = 2;lv_area_t a;a.x1 = 0;a.y1 = 0;a.x2 = size;a.y2 = size;lv_area_align(&obj->coords, &a, LV_ALIGN_CENTER, 0, 0);lv_draw_rect(base_dsc->layer, &draw_dsc, &a);}
}/*** 演示draw事件的使用*/
void lv_example_event_4(void)
{lv_obj_t * cont = lv_obj_create(lv_screen_active());lv_obj_set_size(cont, 200, 200);lv_obj_center(cont);lv_obj_add_event_cb(cont, event_cb, LV_EVENT_DRAW_TASK_ADDED, NULL);lv_obj_add_flag(cont, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS);lv_timer_create(timer_cb, 30, cont);
}#endif
展示:draw事件使用(和android以及其它的一些gui的绘制事件类似,一般用来画圆或者画线,对于初学者来说不用太多深入,暂时了解存在这种方式,可以后续再来深入研究)
三、最后
基本上前三种事件就足够大多数场景用了,嵌入式场景一般不会使用特别复杂的UI设计,但是也需要对绘制事件有一个印象,说不定有独特的设计会需要这种事件来支持,特别是实现一些复杂炫酷动画的时候。