LVGL 主题
修改样式的一点个人心得
lvgl的样式众多,本人是记不住的,用的时候可以快速查找即可
-
查看官方例子
查看官方例子可以快速了解组件的基础样式
-
使用官方的 SquareLineStudio 软件,配置出想要的效果,再生成参考代码
SquareLineStudio 配置界面很是方便,但是奈何UI和其他任务总是分离的不彻底,因此个人习惯只是参考生成的代码,然后利用之前的界面管理工具,为每个界面都创建一个.c文件。
- 参考 lv_theme_default.c 中 theme_apply 函数的相关部分
在 lv_port_disp_init 函数中会应用默认的主题,这也是为什么创建出控件时会自带样式。
对对应控件的默认样式进行屏蔽或修改,测试出要修改样式的部分,然后再恢复默认样式,在创建控件后 使用 lv_obj_set_style_xxxx 单独对控件样式进行修改。
通过修改主题,使字体图片选中时反色
有时候需要全局修改某个控件样式,最简单的就是通过主题修改,当然创建控件后进行单独修改也是可以的。
extern const lv_img_dsc_t CS_ImgSignalWifi;
extern const lv_img_dsc_t CS_ImgSignal4g;
static lv_style_t s_style_bg_color;
static lv_style_t s_style_list_color;
static lv_style_t s_style_focus_bg_color;
static lv_style_t s_style_focus_img_color;
static lv_style_t s_style_text_selected_color;
/**
* @brief 聚焦后改变图片状态 从而改变图片颜色
* @param e
*/
static void img_focus_event_cb(lv_event_t* e)
{
lv_obj_t* btn = lv_event_get_target(e);
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_FOCUSED)
{
for (int i = 0; i < lv_obj_get_child_cnt(btn); i++)
{
lv_obj_t* obj = lv_obj_get_child(btn, i);
if (lv_obj_check_type(obj, &lv_img_class))
{
lv_obj_add_state(obj, LV_STATE_USER_1);
}
}
}
else if (code == LV_EVENT_DEFOCUSED)
{
for (int i = 0; i < lv_obj_get_child_cnt(btn); i++)
{
lv_obj_t* obj = lv_obj_get_child(btn, i);
if (lv_obj_check_type(obj, &lv_img_class))
{
lv_obj_clear_state(obj, LV_STATE_USER_1);
}
}
}
}
/*Will be called when the styles of the base theme are already added
to add new styles*/
static void new_theme_apply_cb(lv_theme_t* th, lv_obj_t* obj)
{
LV_UNUSED(th);
/* 配置下拉列表 主题样式 */
if (lv_obj_check_type(obj, &lv_dropdown_class)) {
lv_obj_add_style(obj, &s_style_bg_color, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_add_style(obj, &s_style_focus_bg_color, LV_PART_MAIN | LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &s_style_focus_bg_color, LV_PART_MAIN | LV_STATE_FOCUSED);
}
if (lv_obj_check_type(obj, &lv_dropdownlist_class)) {
lv_obj_add_style(obj, &s_style_text_selected_color, LV_PART_SELECTED | LV_STATE_CHECKED);
lv_obj_add_style(obj, &s_style_list_color, LV_PART_MAIN | LV_STATE_DEFAULT);
}
/* 配置按键 主题样式 */
if (lv_obj_check_type(obj, &lv_btn_class))
{
/* 选中时样式 */
lv_obj_add_style(obj, &s_style_focus_bg_color, LV_PART_MAIN | LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &s_style_focus_bg_color, LV_PART_MAIN | LV_STATE_FOCUSED);
lv_obj_add_style(obj, &s_style_bg_color, LV_PART_MAIN | LV_STATE_DEFAULT);
}
/* 配置图片 主题样式 */
if (lv_obj_check_type(obj, &lv_img_class))
{
/* LV_STATE_USER_1 时样式 */
lv_obj_add_style(obj, &s_style_focus_img_color, LV_PART_MAIN | LV_STATE_USER_1);
}
}
static lv_obj_t* theme_test(const uint32_t id, void* param)
{
lv_obj_t* screen = lv_obj_create(NULL);
lv_disp_t* dispp = lv_disp_get_default();
lv_theme_t* theme = lv_theme_default_init(dispp, lv_color_hex(0xffff), lv_color_hex(0xffffff), true, &lv_font_montserrat_14);
lv_disp_set_theme(dispp, theme);
#if 1
lv_style_init(&s_style_bg_color);
lv_style_set_bg_color(&s_style_bg_color, lv_color_hex(0x505050));
lv_style_set_bg_opa(&s_style_bg_color, 255);
lv_style_init(&s_style_list_color);
lv_style_set_bg_color(&s_style_list_color, lv_color_hex(0x929495));
lv_style_set_bg_opa(&s_style_list_color, 255);
lv_style_init(&s_style_focus_bg_color);
lv_style_set_bg_color(&s_style_focus_bg_color, lv_color_hex(0xffff));
lv_style_set_text_color(&s_style_focus_bg_color, lv_color_hex(0));
lv_style_set_text_opa(&s_style_focus_bg_color, LV_OPA_100);
lv_style_set_border_width(&s_style_focus_bg_color, 0);
lv_style_set_outline_pad(&s_style_focus_bg_color, 0);
lv_style_set_outline_width(&s_style_focus_bg_color, 0);
lv_style_init(&s_style_focus_img_color);
lv_style_set_img_recolor(&s_style_focus_img_color, lv_color_hex(0x0));
lv_style_set_img_recolor_opa(&s_style_focus_img_color, LV_OPA_100);
lv_style_init(&s_style_text_selected_color);
lv_style_set_text_color(&s_style_text_selected_color, lv_color_hex(0));
lv_theme_t* th_act = lv_disp_get_theme(NULL);
static lv_theme_t th_new;
th_new = *th_act;
/*Set the parent theme and the style apply callback for the new theme*/
lv_theme_set_parent(&th_new, th_act);
lv_theme_set_apply_cb(&th_new, new_theme_apply_cb);
/*Assign the new theme the the current display*/
lv_disp_set_theme(NULL, &th_new);
#endif
lv_obj_t* dropdown = lv_dropdown_create(screen);
lv_dropdown_set_options(dropdown, "Apple\n"
"Banana\n"
"Orange\n"
"Cherry\n"
"Grape\n"
"Raspberry\n"
"Melon\n"
"Orange\n"
"Lemon\n"
"Nuts");
lv_obj_align(dropdown, LV_ALIGN_TOP_MID, 0, 100);
{
lv_obj_t* btn = lv_btn_create(screen);
lv_obj_align(btn, LV_ALIGN_TOP_MID, -100, 20);
lv_obj_set_size(btn, 100, 40);
lv_obj_add_event_cb(btn, img_focus_event_cb, LV_EVENT_ALL, NULL);
lv_obj_t* lab = lv_label_create(btn);
lv_label_set_text(lab, "btn1");
lv_obj_align(lab, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_t* img = lv_img_create(btn);
lv_img_set_src(img, &CS_ImgSignalWifi);
lv_obj_align(img, LV_ALIGN_LEFT_MID, 0, 0);
}
{
lv_obj_t* btn = lv_btn_create(screen);
lv_obj_align(btn, LV_ALIGN_TOP_MID, 100, 20);
lv_obj_set_size(btn, 100, 40);
lv_obj_add_event_cb(btn, img_focus_event_cb, LV_EVENT_ALL, NULL);
lv_obj_t* lab = lv_label_create(btn);
lv_label_set_text(lab, "btn2");
lv_obj_align(lab, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_t* img = lv_img_create(btn);
lv_img_set_src(img, &CS_ImgSignal4g);
lv_obj_align(img, LV_ALIGN_LEFT_MID, 0, 0);
}
return screen;
}
想要图片选中反色,需要使用.png图片,在官网 转换时转换为带透明通道格式的