在 LVGL 中,样式(Style) 是用来控制对象(控件)外观的核心机制,涵盖了 颜色、边框、背景、文字、阴影、渐变、圆角 等视觉特性。通过样式,你可以轻松地为不同状态(如正常、按下、禁用等)指定不同的外观效果。
lv_style_set_bg_color()
、lv_style_set_border_width()
)来设置。bg_color
,则会覆盖先前样式的 bg_color
。 样式存储在 lv_style_t 变量中。LVGL 的样式系统采用了动态分配与静态分配相结合的方式,目的是尽可能地节省内存。
static lv_style_t style_btn_default;
lv_style_init(&style_btn_default); // 初始化样式,确保处于一个已知的、干净的初始状态
lv_style_set_bg_color(&style_btn_default, lv_color_hex(0x000000));
只存储实际设置的属性
样式(lv_style_t)不会为所有可能的视觉属性预留固定空间,而是仅在需要时,通过动态分配(或扩展已有内存)来存储实际设置的属性值。这避免了为未使用的属性浪费内存。
完成样式初始化后,你可以通过以下方式为对象应用样式:
lv_obj_t *btn = lv_btn_create(lv_scr_act()); // 创建一个按钮对象
lv_obj_add_style(btn, &style_btn_default, LV_STATE_DEFAULT); // 应用于默认状态
如果你想在 按钮按下(PRESSED) 时使用不同的颜色,可以再次创建一个样式用于按下状态:
static lv_style_t style_btn_pressed;
lv_style_set_bg_color(&style_btn, lv_color_hex(0x007ACC)); // 改变背景色
lv_obj_add_style(btn, &style_btn_pressed, LV_STATE_PRESSED); // 应用于按下状态
这样,当按钮处于按下状态时,就会显示新的背景色。
假设你要创建一个按钮样式,只改变背景颜色和圆角属性。初始时,你可能这样写
static lv_style_t style_btn;
lv_style_init(&style_btn); // 初始化样式
// 设置背景颜色为红色
lv_style_set_bg_color(&style_btn, lv_color_hex(0xFF0000));
// 设置圆角半径为 5 像素
lv_style_set_radius(&style_btn, 5);
实际情况:
lv_style_init(&style_btn)
时,style_btn.values_and_props
可能为空或分配了一个很小的内存块,因为还没有任何属性被设置。lv_style_set_bg_color(&style_btn, lv_color_hex(0xFF0000));
时,内部会检查这个样式是否已经为背景颜色属性分配了内存。如果没有,它就会分配一个足够存储“背景颜色”这一属性的数据块,然后把属性 ID 和对应的值(红色)存储进去。lv_style_set_radius(&style_btn, 5);
会让系统检查 style_btn.values_and_props
是否有足够空间存储另一个属性(圆角)。如果空间不够,系统会动态扩展该内存块,把新的属性和值也存储进去。这样,只为你真正设置的属性分配内存,而不是预先为所有可能属性保留大量空间。最终,lv_style_t
只占用较小内存,同时能够高效地存储你实际用到的样式属性。这就是 LVGL 为了节省内存而采用动态分配和按需扩展的设计理念。
普通样式通常是以全局定义的方式存在,常见于主题或默认样式中。这类样式在编译时就已经确定好,并且被多个对象共享,内存开销小,因为它们是只读的。
示例:
static lv_style_t style_btn_default;
lv_style_init(&style_btn_default); // 初始化
lv_style_set_bg_color(&style_btn_default, lv_color_hex(0x000000));
lv_style_set_border_width(&style_btn_default, 2);
当你需要对单个对象进行定制化修改,而不希望影响到其他使用相同普通样式的对象时,LVGL 会为该对象创建一个本地样式副本。
lv_obj_t * btn_local = lv_btn_create(lv_scr_act());
lv_obj_set_style_bg_color(btn_local, lv_color_hex(0xFF5722), LV_PART_MAIN);
lv_obj_set_style_radius(btn_local, 8, LV_PART_MAIN);