Styles 用于设置对象的外观。 lvgl 中的样式很大程度上受到 CSS 的启发。简而言之,其概念如下:
- 样式是一个 lv_style_t 变量,它可以保存边框宽度、文本颜色等属性。它类似于 CSS 中的“类”。
- 可以将样式分配给对象以更改其外观。在赋值过程中,可以指定目标部分(CSS 中的pseudo element)和目标状态(pseudo class)。
例如,当滑块处于按下状态时,可以将“style_blue”添加到滑块的旋钮。
-
任何数量的对象都可以使用相同的样式。
-
样式可以级联,这意味着可以将多个样式分配给一个对象,并且每个样式可以具有不同的属性。
因此,并非所有属性都必须在样式中指定。 LVLG 将寻找一个属性,直到一个样式定义它,或者如果它没有被任何样式指定,则使用默认值。
例如,style_btn
可以导致默认的灰色按钮,而style_btn_red
只能添加一个background-color=red
来覆盖背景颜色。
- 后来添加的样式具有更高的优先级。这意味着如果在两种样式中指定了一个属性,则将使用稍后添加的样式。
- 如果对象中未指定某些属性(例如文本颜色),则可以从父级继承。
- 对象可以具有比“正常”样式具有更高优先级的本地样式。
- 与 CSS(伪类描述不同的状态,例如:focus)不同,在 LVGL 中,属性被分配给给定的状态。
- 当对象改变状态时可以应用转换。
States(状态)
LV_STATE_DEFAULT
(0x0000) 正常,释放状态LV_STATE_CHECKED
(0x0001) 切换或检查状态LV_STATE_FOCUSED
(0x0002) 通过键盘或编码器聚焦或通过触摸板/鼠标点击LV_STATE_FOCUS_KEY
(0x0004) 通过键盘或编码器聚焦,但不通过触摸板/鼠标聚焦LV_STATE_EDITED
(0x0008) 由编码器编辑LV_STATE_HOVERED
(0x0010) 鼠标悬停(现在不支持)LV_STATE_PRESSED
(0x0020) 被按下LV_STATE_SCROLLED
(0x0040) 正在滚动LV_STATE_DISABLED
(0x0080) 禁用状态LV_STATE_USER_1
(0x1000) 自定义状态LV_STATE_USER_2
(0x2000) 自定义状态LV_STATE_USER_3
(0x4000) 自定义状态LV_STATE_USER_4
(0x8000) 自定义状态
该组合表示可以同时聚焦和按下对象。这表示为LV_STATE_FOCUSED | LV_STATE_PRESSED
。
样式可以添加到任何状态和状态组合。 例如,为默认和按下状态设置不同的背景颜色。 如果属性未在状态中定义,则将使用最佳匹配状态的属性。通常这意味着使用带有“LV_STATE_DEFAULT”的属性。 如果即使为默认状态也未设置该属性,则将使用默认值。
Cascading styles(层叠样式)
不需要在一种样式中设置所有属性。可以向对象添加更多样式,并让稍后添加的样式修改或扩展外观。 例如,创建一个通用的灰色按钮样式并为红色按钮创建一个新的,其中只设置了新的背景颜色。
这很像在 CSS 中,当使用的类像<div class=".btn .btn-red">
一样列出时。
后来添加的样式优先于之前设置的样式。所以在上面的灰色/红色按钮示例中,应该首先添加普通按钮样式,然后添加红色样式。 但是,仍然考虑来自州的优先权。 因此,让我们检查以下案例:
基本按钮样式定义了默认状态的深灰色和浅灰色按下状态
红色按钮样式仅在默认状态下将背景颜色定义为红色
在这种情况下,当按钮被释放(处于默认状态)时,它将是红色的,因为在最近添加的样式(红色)中找到了完美匹配。 当按下按钮时,浅灰色更适合,因为它完美地描述了当前状态,所以按钮将是浅灰色。
Inheritance(继承)
某些属性(通常与文本相关)可以从父对象的样式继承。 仅当未在对象的样式中设置给定属性时(即使在默认状态下),才应用继承。 在这种情况下,如果该属性是可继承的,则该属性的值也将在父项中搜索,直到一个对象为该属性指定了一个值。父母将使用自己的状态来确定该值。 因此,如果按下按钮,并且文本颜色来自此处,则将使用按下的文本颜色。
Parts
LV_PART_MAIN
类似矩形的背景*/LV_PART_SCROLLBAR
滚动条LV_PART_INDICATOR
指标,例如用于滑块、条、开关或复选框的勾选框LV_PART_KNOB
像手柄一样可以抓取调整值*/LV_PART_SELECTED
表示当前选择的选项或部分LV_PART_ITEMS
如果小部件具有多个相似元素(例如表格单元格)*/LV_PART_TICKS
刻度上的刻度,例如对于图表或仪表LV_PART_CURSOR
标记一个特定的地方,例如文本区域或图表的光标LV_PART_CUSTOM_FIRST
可以从这里添加自定义部件。
Initialize styles and set/get properties(初始化样式和设置/获取属性)
样式存储在 lv_style_t
变量中。样式变量应该是“静态”、全局或动态分配的。 换句话说,它们不能是函数中的局部变量,当函数存在时它们会被销毁。 在使用样式之前,它应该用 lv_style_init(&my_style)
进行初始化。 初始化后,可以设置或添加样式属性。
属性集函数看起来像这样:lv_style_set_<property_name>(&style, <value>)
; 例如:
static lv_style_t style_btn;
lv_style_init(&style_btn);//初始化
lv_style_set_bg_color(&style_btn, lv_color_grey());//设置背景颜色
lv_style_set_bg_opa(&style_btn, LV_OPA_50);//设置背景颜色透明度
lv_style_set_border_width(&style_btn, 2);//设置按键边宽度
lv_style_set_border_color(&style_btn, lv_color_black());//按键边颜色
static lv_style_t style_btn_red;
lv_style_init(&style_btn_red);
lv_style_set_bg_color(&style_btn_red, lv_color_red());
lv_style_set_bg_opa(&style_btn_red, LV_OPA_COVER);
删除属性
lv_style_remove_prop(&style, LV_STYLE_BG_COLOR);
从样式中获取属性的值
lv_style_value_t v;
lv_res_t res = lv_style_rget_prop(&style, LV_STYLE_BG_COLOR, &v);
if(res == LV_RES_OK) { /*Found*/
do_something(v.color);
}
要重置样式(释放其所有数据),请使用
lv_style_reset(&style);
Add and remove styles to a widget(向部件添加和删除样式)
一个样式本身并没有那么有用,它需要分配给一个对象才能生效。
Add styles(添加样式)
要向对象添加样式,请使用 lv_obj_add_style(obj, &style, <selector>)
。 <selector>
是应添加样式的部分和状态的 OR 值。一些例子:
-
LV_PART_MAIN | LV_STATE_DEFAULT
-
LV_STATE_PRESSED
:处于按下状态的主要部分。 LV_PART_MAIN 可以省略 -
LV_PART_SCROLLBAR
:默认状态下的滚动条部分。 LV_STATE_DEFAULT 可以省略。 -
LV_PART_SCROLLBAR | LV_STATE_SCROLLED
:对象滚动时的滚动条部分0
与LV_PART_MAIN
| 相同LV_STATE_DEFAULT
。 -
LV_PART_INDICATOR | LV_STATE_PRESSED | LV_STATE_CHECKED
同时按下和检查对象时的指示器部分。
使用 lv_obj_add_style 的示例:
lv_obj_add_style(btn, &style_btn, 0); /*Default button style*/
lv_obj_add_style(btn, &btn_red, LV_STATE_PRESSED); /*Overwrite only a some colors to red when pressed*/
Remove styles(删除样式)
要从对象中删除所有样式,请使用 lv_obj_remove_style_all(obj)
。
要删除特定样式,请使用 lv_obj_remove_style(obj, style, selector)
。仅当 selector
与 lv_obj_add_style
中使用的 selector
匹配时,此函数才会删除 style
。 style
可以是 NULL
以仅检查 selector
并删除所有匹配的样式。 selector
可以使用 LV_STATE_ANY
和 LV_PART_ANY
值来删除具有任何状态或部分的样式。
Report style changes(通知样式更改)
如果已分配给对象的样式发生更改(即添加或更改属性),则应通知使用该样式的对象。有 3 个选项可以执行此操作:
-
1.如果您知道更改的属性可以通过简单的重绘(例如颜色或不透明度更改)应用,只需调用
lv_obj_invalidate(obj)
或lv_obj_invalidate(lv_scr_act())
。 -
2.如果更改或添加了更复杂的样式属性,并且您知道哪些对象受该样式影响,则调用
lv_obj_refresh_style(obj, part, property)
。 要刷新所有部件和属性,请使用lv_obj_refresh_style(obj, LV_PART_ANY, LV_STYLE_PROP_ANY)
。 -
3.要让 LVGL 检查所有对象是否使用该样式并在需要时刷新它们,请调用
lv_obj_report_style_change(&style)
。如果style
为NULL
,所有对象都会收到有关样式更改的通知。
Properties(属性)
Typical background properties(典型的背景属性)
- Background
- Border
- Outline
- Shadow
- Padding
- Width and height transformation
- X and Y translation
Transitions(过渡特效)
默认情况下,当一个对象改变状态(例如它被按下)时,新状态的新属性会立即设置。但是,通过转换,可以在状态更改时播放动画。 例如,按下按钮时,其背景颜色可以在 300 毫秒内动画显示为按下的颜色。
过渡的参数存储在样式中。可以设置
- 过渡时期
- 开始过渡前的延迟
- 动画路径(也称为计时或缓动功能)
- 动画的属性
可以为每个状态定义转换属性。例如,在默认状态下设置 500 ms 转换时间意味着当对象进入默认状态时,将应用 500 ms 转换时间。 在按下状态设置 100 ms 转换时间将意味着在进入按下状态时有 100 ms 转换时间。 因此,此示例配置将导致快速进入按下状态,然后缓慢返回默认状态。
要描述转换,需要初始化 lv_transition_dsc_t
变量并将其添加到样式中:
/*Only its pointer is saved so must static, global or dynamically allocated */
static const lv_style_prop_t trans_props[] = {
LV_STYLE_BG_OPA, LV_STYLE_BG_COLOR,
0, /*End marker*/
};
static lv_style_transition_dsc_t trans1;
lv_style_transition_dsc_init(&trans1, trans_props, lv_anim_path_ease_out, duration_ms, delay_ms);
lv_style_set_transition(&style1, &trans1);