2、样式属性详解(上):背景属性(颜色、渐变、圆角、透明度)
好,咱们今天来聊聊LVGL里最基础、也最常用的几个背景属性。说实话,我刚开始用LVGL做项目时,觉得背景嘛,不就是填个颜色?后来踩的坑多了才发现,这里面的门道还真不少。颜色、渐变、圆角、透明度,这四个属性组合好了,能让你的界面质感直接上一个台阶。
2.1 背景颜色:不只是填色那么简单
先说说最基础的背景颜色。在LVGL里,背景颜色由 lv_style_set_bg_color() 这个函数控制。嗯,这里要注意,它接受的是 lv_color_t 类型,不是RGB字符串。
// 设置一个纯红色背景
lv_style_set_bg_color(&style, lv_color_hex(0xFF0000));
// 或者用RGB方式
lv_style_set_bg_color(&style, lv_color_make(255, 0, 0));
我个人习惯用 lv_color_hex(),因为从设计稿上复制颜色值特别方便。但有个坑——LVGL的颜色格式默认是RGB565,也就是16位色。你传进去的0xFF0000,实际显示效果可能会偏色。我在项目中遇到过,设计给的是纯红(0xFF0000),结果屏幕上看起来有点发紫。后来查了文档才发现,RGB565下红色只有5位精度,0xFF会被截断成0xF8。
LV_COLOR_DEPTH 改成 32。我曾经因为这个问题,整整调了一下午的颜色,最后发现是色深设置不对。
2.2 背景渐变:让界面活起来
纯色背景看久了会腻,对吧?LVGL的渐变功能就能解决这个问题。它支持线性渐变,方向可以设置成水平、垂直或者任意角度。
渐变需要设置三个东西:渐变方向、起始颜色、结束颜色。代码长这样:
// 设置从上到下的渐变
lv_style_set_bg_grad_dir(&style, LV_GRAD_DIR_VER);
lv_style_set_bg_grad_color(&style, lv_color_hex(0x0000FF)); // 底部蓝色
lv_style_set_bg_color(&style, lv_color_hex(0xFF0000)); // 顶部红色
你想想看,这里有个容易搞混的地方——bg_color 是渐变的起始色,bg_grad_color 才是结束色。我刚开始用的时候,总以为 bg_grad_color 是起始色,结果渐变方向反了。
LV_GRAD_DIR_NONE 来关闭渐变。我个人习惯在按钮的按下状态用垂直渐变,模拟出凹陷的立体感。
渐变还有个隐藏属性——bg_grad_stop。它可以让你在渐变中插入中间色,实现多色渐变。不过说实话,这个功能我用的不多,因为嵌入式设备的性能有限,多色渐变会消耗更多CPU。
2.3 圆角:从硬朗到圆润
圆角是UI设计中提升亲和力的利器。LVGL里用 lv_style_set_radius() 来控制。默认值是0,也就是直角。
// 设置圆角半径为10像素
lv_style_set_radius(&style, 10);
// 设置成圆形(适用于正方形控件)
lv_style_set_radius(&style, LV_RADIUS_CIRCLE);
LV_RADIUS_CIRCLE 这个宏的值是 LV_COORD_MAX,它会自动计算成控件宽高的一半。嗯,这里要注意,如果你的控件是长方形,用 LV_RADIUS_CIRCLE 会得到一个胶囊形状,不是正圆。
我在项目中遇到过一个问题:给一个按钮设置了圆角,但按钮的边框还是直角的。后来发现,圆角只影响背景和边框的裁剪区域,如果你单独设置了边框颜色,边框也会跟着圆角走。但如果你的边框是图片或者特殊样式,那就得另想办法了。
2.4 透明度:层次感的灵魂
透明度,说白了就是让背景能透出底下的内容。LVGL用 lv_style_set_bg_opa() 来控制,取值范围是0(完全透明)到255(完全不透明)。
// 设置半透明背景
lv_style_set_bg_opa(&style, 128); // 50%透明度
// 完全透明
lv_style_set_bg_opa(&style, LV_OPA_TRANSP);
// 完全不透明
lv_style_set_bg_opa(&style, LV_OPA_COVER);
这里有个性能相关的知识点——透明度会触发重绘。如果你在一个频繁刷新的控件上用了透明度,CPU占用率会明显上升。我曾经在一个实时数据显示界面上用了半透明背景,结果刷新率从60fps掉到了30fps。后来改成完全不透明,问题就解决了。
2.5 综合示例:一个现代风格的卡片
好了,理论知识讲完了,咱们来个实战。下面这个例子,把颜色、渐变、圆角、透明度都用上了,做一个现代风格的卡片背景:
/* 创建一个卡片样式 */
static lv_style_t style_card;
lv_style_init(&style_card);
/* 背景:从上到下的渐变,从深蓝到浅蓝 */
lv_style_set_bg_color(&style_card, lv_color_hex(0x1a237e)); // 深蓝
lv_style_set_bg_grad_color(&style_card, lv_color_hex(0x42a5f5)); // 浅蓝
lv_style_set_bg_grad_dir(&style_card, LV_GRAD_DIR_VER);
/* 圆角:12像素,看起来更柔和 */
lv_style_set_radius(&style_card, 12);
/* 透明度:稍微透明一点,让背景透出来 */
lv_style_set_bg_opa(&style_card, 200); // 约78%不透明
/* 应用到控件上 */
lv_obj_t * card = lv_obj_create(lv_scr_act());
lv_obj_add_style(card, &style_card, 0);
这个卡片的效果是:顶部深蓝,底部浅蓝,中间平滑过渡,四个角是圆润的,而且能隐约看到底层的背景。我个人觉得这种风格很适合用在仪表盘或者信息展示页面上。
2.6 属性优先级与继承
最后说一个容易忽略的点——这些背景属性是可以继承的。如果你在父控件上设置了背景颜色,子控件没有设置,那子控件会继承父控件的背景。但渐变和圆角不会继承,它们只作用于当前控件。
| 属性 | 是否可继承 | 默认值 |
|---|---|---|
| bg_color | 是 | 0xFFFFFF(白色) |
| bg_grad_color | 否 | 0x000000(黑色) |
| bg_grad_dir | 否 | LV_GRAD_DIR_NONE |
| radius | 否 | 0 |
| bg_opa | 是 | LV_OPA_COVER |
嗯,这个表格你记一下,调试的时候特别有用。我经常遇到子控件莫名其妙变透明了,查了半天发现是父控件设置了透明度,子控件继承了。
好了,背景属性的上半部分就讲到这里。下一节咱们继续聊边框、阴影和轮廓,这些属性组合起来,就能做出真正有质感的UI了。