《lvgl基础学习 —— lv_style》
1.lv_style
lv_style用来控制对象的外观:颜色、字体、圆角、边框、间距等。
没有样式时:
-
按钮像“灰盒子”
-
UI 看起来很“Demo”
有样式后:
-
有品牌色
-
有层次
-
有一致风格
样式 = UI 的“皮肤系统”
LVGL样式的核心认知:
1.样式 不等于 对象
2.一个样式可以给多个对象用
3.一个对象可以叠加多个样式
样式的基本使用流程:
static lv_style_t style; lv_style_init(&style); lv_style_set_bg_color(&style, lv_color_hex(0x007AFF)); lv_style_set_radius(&style, 10); lv_obj_add_style(obj, &style, 0);
demo:蓝色圆角按钮
static lv_style_t style_btn; void ui_style_demo(void) { lv_style_init(&style_btn); lv_style_set_bg_color(&style_btn, lv_color_hex(0x007AFF)); lv_style_set_bg_opa(&style_btn, LV_OPA_COVER); lv_style_set_radius(&style_btn, 12); lv_style_set_text_color(&style_btn, lv_color_white()); lv_obj_t *btn = lv_btn_create(lv_scr_act()); lv_obj_set_size(btn, 160, 60); lv_obj_center(btn); lv_obj_add_style(btn, &style_btn, 0); lv_obj_t *label = lv_label_create(btn); lv_label_set_text(label, "Styled Button"); lv_obj_center(label); }
常用的样式属性
背景相关:
lv_style_set_bg_color(&style, lv_color_hex(0x333333)); lv_style_set_bg_opa(&style, LV_OPA_COVER);
圆角:
lv_style_set_radius(&style, 10);
边框:
lv_style_set_border_width(&style, 2); lv_style_set_border_color(&style, lv_color_hex(0xAAAAAA));
文字:
lv_style_set_text_color(&style, lv_color_white());
lv_style_set_text_font(&style, &lv_font_montserrat_18);
内边距:
lv_style_set_pad_all(&style, 10);
样式和“状态”的关系:
LVGL 的对象有状态:
LV_STATE_DEFAULT
LV_STATE_PRESSED
LV_STATE_CHECKED
LV_STATE_DISABLED
同一个对象,不同状态,可以用不同样式。
demo:按钮按下变深色
static lv_style_t style_btn; static lv_style_t style_btn_pressed; void ui_style_state_demo(void) { lv_style_init(&style_btn); lv_style_set_bg_color(&style_btn, lv_color_hex(0x007AFF)); lv_style_set_radius(&style_btn, 12); lv_style_init(&style_btn_pressed); lv_style_set_bg_color(&style_btn_pressed, lv_color_hex(0x005BBB)); lv_obj_t *btn = lv_btn_create(lv_scr_act()); lv_obj_set_size(btn, 160, 60); lv_obj_center(btn); lv_obj_add_style(btn, &style_btn, LV_STATE_DEFAULT); lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED); lv_obj_t *label = lv_label_create(btn); lv_label_set_text(label, "Press me"); lv_obj_center(label); }
样式复用
错误做法:
lv_style_t s; lv_style_init(&s); /* 用一次就丢 */
正确做法:
static lv_style_t style_btn_primary; static lv_style_t style_label_title; void ui_style_init(void) { lv_style_init(&style_btn_primary); lv_style_set_bg_color(&style_btn_primary, lv_color_hex(0x007AFF)); }
demo:设置项(label + switch)
static lv_style_t style_row; void ui_style_layout_demo(void) { lv_style_init(&style_row); lv_style_set_pad_all(&style_row, 10); lv_style_set_border_width(&style_row, 1); lv_style_set_border_color(&style_row, lv_color_hex(0xDDDDDD)); lv_style_set_radius(&style_row, 8); lv_obj_t *cont = lv_obj_create(lv_scr_act()); lv_obj_set_size(cont, 300, 200); lv_obj_center(cont); lv_obj_set_layout(cont, LV_LAYOUT_FLEX); lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN); for(int i = 0; i < 3; i++) { lv_obj_t *row = lv_obj_create(cont); lv_obj_set_size(row, LV_PCT(100), 50); lv_obj_add_style(row, &style_row, 0); lv_obj_set_layout(row, LV_LAYOUT_FLEX); lv_obj_set_flex_flow(row, LV_FLEX_FLOW_ROW); lv_obj_set_flex_align(row, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); lv_obj_t *label = lv_label_create(row); lv_label_set_text_fmt(label, "Option %d", i + 1); lv_switch_create(row); } }
新手最常见的 8 个坑
❌ 1️⃣ 忘了 lv_style_init
→ 样式无效 / 崩溃
❌ 2️⃣ 样式是局部变量
→ UI 运行一会儿就异常
❌ 3️⃣ 在回调里频繁 lv_style_init
→ 性能差
❌ 4️⃣ 想改颜色却改了 label
→ 实际该改父对象
❌ 5️⃣ 不区分状态样式
→ UI 没反馈感
❌ 6️⃣ 用样式控制位置
→ 布局应该用 layout
❌ 7️⃣ 样式太多、无规范
→ 后期维护灾难
❌ 8️⃣ 一上来就 theme
→ 先学 style 再学 theme
浙公网安备 33010602011771号