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_conf.h 里把 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。后来改成完全不透明,问题就解决了。

避坑指南: 透明度是叠加计算的。如果一个父控件设置了50%透明度,子控件又设置了50%透明度,那子控件的实际透明度是25%。我曾经因为这个,调试了半天为什么子控件看起来那么淡。

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了。