一、LVGL样式概述
1、创建样式
在 LVGL 中,样式都是以对象的方式存在,一个对象可以描述一种样式。每个控件都可以独立添加样式,创建的样式之间互不影响。
可以使用 lv_style_t
类型创建一个样式并初始化:
static lv_style_t style;
lv_style_init(&style);
样式是延迟渲染的,因此需要使用 static
存储类别说明符或将其声明为全局变量。
样式是多方面的,不仅包括颜色和形状,还包括边距、边框,甚至动画变换效果等细节。
二、样式属性
1、尺寸和位置
要理解尺寸和位置是如何起作用的,首先要理解 LVGL 的盒子模型。官方文档给出了一张图,可以很好地描述一个控件的框架结构:
在设置尺寸的时候,长和宽指的是包括边框(border)厚度的长宽,也就是不包括轮廓(outline)的总长宽。
在设置位置的时候,设置的坐标指的是 border 左上角相对父容器的 Content area 的坐标,也就是说如果设置坐标为 0 的话,轮廓(outline)可能会被父容器的边框(border)遮盖。
下表总结了尺寸与位置有关的可用属性有:
属性 | 描述 | 默认值 |
---|---|---|
width | 宽度 | 由控件类别决定 |
min_width | 最小宽度 | 0 |
max_width | 最大宽度 | 屏幕的宽度 |
height | 高度 | 由控件类别决定 |
min_height | 最小宽度 | 0 |
max_height | 最大宽度 | 屏幕的高度 |
align | 对齐方式 | 左上方 |
x | 对齐后在水平方向的偏移量 | 0 |
y | 对齐后在竖直方向的偏移量 | 0 |
注意这里有一个最小或最大的宽度和高度,可以给它们提供一个阈值防止过大或过小。
在设置宽度和高度时,除了使用确定的数值外,还可以使用百分比值 lv_pct(x)
来设置控件相对父容器的 Content area 的大小或位置。例如,样式
lv_style_set_width(&style, lv_pct(25));
lv_style_set_x(&style, lv_pct(50));
可以让一个控件的水平尺寸占据父容器的 1/2~3/4 的位置:
对于父容器而言,还可以使用 LV_SIZE_CONTENT
特殊单位调整其尺寸至可以容纳所有包含控件的合适值。例如,按钮就是一个这样的容器,它的默认样式就通过该值使得其宽度和高度可以自动适应包含的标签尺寸。
2、边框和边距
上图展示的文本框就有一个深灰色的边框。边框就无需额外描述了,与边框有关的样式属性有:
属性 | 描述 | 默认值 |
---|---|---|
border_width | 边框宽度,只能用绝对宽度描述 | 0 |
border_side | 绘制哪些部分的边框 | LV_SIDE_ALL |
border_post | 绘制顺序,设置 true 表示包含的子控件绘制完成了再绘制边框 | false |
... | 与颜色有关的属性将在之后介绍 |
边框和主体部分之间被边距(padding)隔开。和边距有关的样式属性有:
属性 | 描述 | 默认值 |
---|---|---|
pad_top | 上边距 | 0 |
pad_bottom | 下边距 | 0 |
pad_left | 左边距 | 0 |
pad_right | 右边距 | 0 |
pad_row | 当控件拥有布局时,每行间的间距 | 0 |
pad_column | 当控件拥有布局时,每列间的间距 | 0 |
不过在设置布局时,还提供了几个简写属性:可以使用 ...pad_all()
一并设置上下左右的边距;或使用 ...pad_hor()
和 ...pad_ver()
设置水平和垂直的边距;还可以使用 ...pad_gap()
设置行和列的间距。
3、轮廓
轮廓(outline)类似边框,但轮廓并不算在一个控件的主体内,因此设置坐标、尺寸等属性时都不包含轮廓的尺寸。
轮廓可设置的属性远比边框少。下表列出了轮廓的一些属性:
属性 | 描述 | 默认值 |
---|---|---|
outline_width | 轮廓宽度 | 0 |
outline_pad | 轮廓到主体的间距 | 0 |
... | 与颜色有关的属性将在之后介绍 |
轮廓和边框最根本的差异是两者不是同一个东西,因此可以在同一个元素同时使用不同样式的轮廓的边框来实现一些有趣的效果。
4、阴影
阴影可以使控件看起来有立体感。下表列出了设置阴影的一些属性:
属性 | 描述 | 默认值 |
---|---|---|
shadow_width | 设置阴影的模糊半径 | 0 |
shadow_ofs_x | 设置阴影的水平偏移量 | 0 |
shadow_ofs_y | 设置阴影的垂直偏移量 | 0 |
shadow_spread | 设置阴影的放大量 | 0 |
... | 与颜色有关的属性将在之后介绍 |
例如,以下设置模糊半径为 50 的蓝色阴影:
LVGL 中无法给同一个控件设置多个阴影叠加,从而实现更复杂的效果,这是比较可惜的一点。
5、文本样式
在创建控件时经常要使用文字,下表列出了能影响文字效果的一些属性:
属性 | 描述 | 默认值 |
---|---|---|
text_font | 设置文字的字体 | 默认字体 |
text_letter_space | 字符间隔 | 0 |
text_line_space | 设置多行文本的行间距 | 0 |
text_decor | 设置文本装饰(下划线或删除线) | LV_TEXT_DECOR_NONE |
text_align | 设置文本对齐方式 | LV_TEXT_ALIGN_AUTO |
... | 与颜色有关的属性将在之后介绍 |
需要注意的是,文本的样式是可继承的,意思是如果子控件没有特别指定的话,它会使用父容器设置的文本样式。
在一段文本内可能存在许多种样式,对此,可以使用类似 CSS 的 span 来拆分样式在文本内的作用域。
span-group 提供的以下函数顶用它对比浮签更符合用于拍卖大段的文件:
函数 | 介绍 |
---|---|
lv_spangroup_set_align(obj, align) | 设置文本框中文本的对齐方式,可以设置为左对齐、居中对齐或右对齐 |
lv_spangroup_set_overflow(obj, overflow) | 设置文本框中文本的溢出处理方式,可以设置为自动换行、截断或滚动 |
lv_spangroup_set_indent(obj, indent) | 设置文本框中文本的缩进,可以设置为左缩进、右缩进或无缩进 |
lv_spangroup_set_mode(obj, mode) | 设置文本框中文本的换行模式,可以设置为自动换行或不换行,不换行时是将文本框的宽度调整为文本的宽度 |
一个 span-group 可以创建多个 span ,并且它们的样式效果互不影响:
lv_obj_t* spangroup = lv_spangroup_create(lv_scr_act());
lv_obj_set_size(spangroup, 160, LV_SIZE_CONTENT);
lv_span_t* span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "LVGL is an open-source graphics library");
lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_BLUE));
span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "providing everything");
lv_style_set_text_decor(&span->style, LV_TEXT_DECOR_UNDERLINE);
lv_style_set_text_font(&span->style, &lv_font_montserrat_20);
/* ... */
span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "to create embedded GUI");
效果为:
可以注意到默认的 span-group 是没什么样式的。
6、其它样式
下表列出了一些其它的样式属性:
属性 | 描述 | 默认值 |
---|---|---|
radius | 设置控件的圆角,该属性会一并影响边框和轮廓 | 0,即无圆角 |
clip_corner | 如果有圆角,是否要将 Content-aera 超出圆角的部分去除 | 否 |
layout | 设置控件的布局方式 | 0 |
base_dir | 设置文字的书写方向,它会同时影响布局的方向 | 默认书写方向 |
... | 与颜色有关的属性将在之后介绍 |
在设置半径时可以使用百分数,例如 lv_pct(50)
将使控件变成圆形。
三、参考资料:
Styles — LVGL documentation
官方文档——样式简介
Style properties — LVGL documentation
官方文档——所有的样式属性简介