属性
尺寸和位置
要理解尺寸和位置是如何起作用的,首先要理解 LVGL 的盒子模型。官方文档给出了一张图,可以很好地描述一个控件的框架结构:
在设置尺寸的时候,长和宽指的是包括边框(border)厚度的长宽,也就是不包括轮廓(outline)的总长宽。
在设置位置的时候,设置的坐标指的是 border 左上角相对父容器的 Content area 的坐标,也就是说如果设置坐标为 0 的话,轮廓(outline)可能会被父容器的边框(border)遮盖。
下表总结了尺寸与位置有关的可用属性有:
注意这里有一个最小或最大的宽度和高度,在上一节介绍 flex 和 grid 布局时就展示过控件宽度随布局自动调整的情况,因此可以给它们提供一个阈值防止过大或过小。
不过上一节还有一个地方没有提到:在设置宽度和高度时,除了使用确定的数值外,还可以使用百分比值 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 特殊单位调整其尺寸至可以容纳所有包含控件的合适值。例如,按钮就是一个这样的容器,它的默认样式就通过该值使得其宽度和高度可以自动适应包含的标签尺寸。
边框和边距
上图展示的文本框就有一个深灰色的边框。边框就无需额外描述了,与边框有关的样式属性有:
边框和主体部分之间被边距(padding)隔开。和边距有关的样式属性有:
不过在设置布局时,还提供了几个简写属性:可以使用 …pad_all() 一并设置上下左右的边距;或使用 …pad_hor() 和 …pad_ver() 设置水平和垂直的边距;还可以使用 …pad_gap() 设置行和列的间距。
轮廓
轮廓(outline)类似边框,但轮廓并不算在一个控件的主体内,因此设置坐标、尺寸等属性时都不包含轮廓的尺寸。
轮廓可设置的属性远比边框少。下表列出了轮廓的一些属性:
轮廓和边框最根本的差异是两者不是同一个东西,因此可以在同一个元素同时使用不同样式的轮廓的边框来实现一些有趣的效果,例如:
lv_style_set_radius(&style, 0);
lv_style_set_border_color(&style, lv_palette_main(LV_PALETTE_GREY));
lv_style_set_border_width(&style, 5);
lv_style_set_border_opa(&style, LV_OPA_COVER);
lv_style_set_border_side(&style, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_RIGHT);
lv_style_set_outline_width(&style, 4);
lv_style_set_outline_pad(&style, 1);
lv_style_set_outline_color(&style, lv_palette_lighten(LV_PALETTE_GREY, 1));
阴影
阴影可以使控件看起来有立体感。下表列出了设置阴影的一些属性:
例如,以下设置模糊半径为 50 的蓝色阴影:
lv_style_set_shadow_width(&style, 50);
lv_style_set_shadow_color(&style, lv_palette_main(LV_PALETTE_BLUE));
以下设置放大有偏移的红色阴影:
lv_style_shadow_color(&style, lv_palette_main(LV_PALETTE_RED))
lv_style_set_shadow_width(&style, 15)
lv_style_set_shadow_ofs_x(&style, 10)
lv_style_set_shadow_ofs_y(&style, 20)
lv_style_set_shadow_spread(&style, 10)
文本样式
在创建控件时经常要使用文字,下表列出了能影响文字效果的一些属性:
需要注意的是,文本的样式是可继承的,意思是如果子控件没有特别指定的话,它会使用父容器设置的文本样式。
在一段文本内可能存在许多种样式,对此,可以使用类似 CSS 的 span 来拆分样式在文本内的作用域。为了创建 span ,首先需要创建一个 span-group :
lv_obj_t* spangroup = lv_spangroup_create(lv_scr_act());
lv_obj_set_size(spangroup, 160, LV_SIZE_CONTENT);
创建的 span-group 和一般的控件没什么区别,可以给它添加一些样式:
lv_obj_set_style_border_color(spangroup, lv_palette_main(LV_PALETTE_BLUE), 0);
lv_obj_set_style_border_width(spangroup, 1, 0);
lv_obj_set_style_pad_all(spangroup, 5, 0);
span-group 提供的以下函数使得它相比标签更适合用来处理大段的文本:
有了 span-group 以后,可以使用以下代码从中创建一个 span 并设置文本:
lv_span_t* span = lv_spangroup_new_span(spangroup);
lv_span_set_text(span, "LVGL is an open-source graphics library");
每一个 span 都提供了一个独立的样式接口,可以单独设置范围内文本的样式:
lv_style_set_text_color(&span->style, lv_palette_main(LV_PALETTE_BLUE));
一个 span-group 可以创建多个 span ,并且它们的样式效果互不影响:
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 是没什么样式的。span-group 还有很多的 API ,具体可以参照官方文档的相关介绍。