3、样式属性详解(中):边框属性(宽度、颜色、样式、边距)
好,咱们接着聊样式属性。上一节我们把背景和圆角讲透了,这一节轮到边框了。说实话,边框在嵌入式UI里是个「又爱又恨」的东西——用好了能提升质感,用不好就是灾难。我早期做的一个工业控制面板项目,就因为边框没处理好,被客户吐槽「像玩具」。
边框属性在LVGL里其实就四个核心维度:宽度、颜色、样式、边距。别小看这四个参数,组合起来能玩出花来。咱们一个一个拆。
3.1 边框宽度(border_width)
边框宽度,说白了就是边框有多粗。单位是像素,默认是0(也就是不显示)。
/* 设置边框宽度为2像素 */
lv_obj_set_style_border_width(obj, 2, LV_STATE_DEFAULT);
我个人习惯把边框宽度控制在1~4像素之间。太细了看不清,太粗了又显得笨重。你想想看,一个按钮如果边框8像素,那视觉上会非常突兀。
3.2 边框颜色(border_color)
边框颜色就简单了,直接给个颜色值。但这里有个坑——边框颜色和背景颜色是叠加的。
/* 设置边框颜色为红色 */
lv_obj_set_style_border_color(obj, lv_color_hex(0xFF0000), LV_STATE_DEFAULT);
嗯,这里要注意:如果你设置了边框宽度为0,那颜色设了也白设。我见过不少新手在这上面浪费时间,调了半天颜色发现没变化,最后发现是宽度没开。
| 场景 | 推荐边框颜色 | 说明 |
|---|---|---|
| 普通按钮 | 比背景深20% | 增加层次感 |
| 选中状态 | 主题色 | 突出显示 |
| 错误提示 | 红色系 | 警示作用 |
| 禁用状态 | 灰色系 | 降低视觉权重 |
3.3 边框样式(border_opa 和 border_side)
边框样式这块,LVGL提供了两个关键属性:透明度(border_opa)和显示方向(border_side)。
3.3.1 边框透明度
/* 设置边框半透明 */
lv_obj_set_style_border_opa(obj, LV_OPA_50, LV_STATE_DEFAULT);
透明度这个属性,说实话我用的不多。但在做「悬浮效果」时特别好用——比如一个卡片,正常状态边框透明度80,按下时变成100,视觉上就有「浮起来」的感觉。
3.3.2 边框显示方向
这个就厉害了。LVGL允许你只显示某几条边,而不是四边全显示。
/* 只显示底部边框 */
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_BOTTOM, LV_STATE_DEFAULT);
/* 显示左右边框 */
lv_obj_set_style_border_side(obj, LV_BORDER_SIDE_LEFT | LV_BORDER_SIDE_RIGHT, LV_STATE_DEFAULT);
LV_BORDER_SIDE_NONE(无边框)、LV_BORDER_SIDE_TOP、LV_BORDER_SIDE_BOTTOM、LV_BORDER_SIDE_LEFT、LV_BORDER_SIDE_RIGHT、LV_BORDER_SIDE_FULL(全显示)、LV_BORDER_SIDE_INTERNAL(内部边框,用于表格等)。
为什么需要这个?我举个例子:做列表项时,通常只需要底部一条分割线。如果四边都画,反而显得杂乱。用LV_BORDER_SIDE_BOTTOM就能完美实现「分割线效果」。
3.4 边框边距(border_width 与 padding 的关系)
这里要澄清一个概念:LVGL里没有独立的「边框边距」属性。边框是紧贴着内容区域的,它的「边距」实际上是通过padding来控制的。
说白了,边框的位置是在padding的外边界上。如果你设置了padding:10,边框宽度:2,那实际占用的空间是:内容区 + padding(10) + 边框(2)。
/* 示例:带边框的卡片 */
lv_obj_t * card = lv_obj_create(parent);
lv_obj_set_size(card, 200, 100);
lv_obj_set_style_pad_all(card, 10, LV_STATE_DEFAULT); /* 内边距10 */
lv_obj_set_style_border_width(card, 2, LV_STATE_DEFAULT); /* 边框宽度2 */
lv_obj_set_style_border_color(card, lv_color_hex(0xCCCCCC), LV_STATE_DEFAULT);
3.5 实战组合:一个带边框的卡片
好了,理论说完了,咱们来点实际的。下面这个例子,是我在智能家居面板项目中常用的卡片样式:
/* 创建一个卡片 */
lv_obj_t * card = lv_obj_create(parent);
lv_obj_set_size(card, 150, 80);
lv_obj_center(card);
/* 背景和圆角 */
lv_obj_set_style_bg_color(card, lv_color_hex(0xFFFFFF), LV_STATE_DEFAULT);
lv_obj_set_style_radius(card, 8, LV_STATE_DEFAULT);
/* 边框设置 */
lv_obj_set_style_border_width(card, 2, LV_STATE_DEFAULT);
lv_obj_set_style_border_color(card, lv_color_hex(0x2196F3), LV_STATE_DEFAULT);
lv_obj_set_style_border_side(card, LV_BORDER_SIDE_LEFT, LV_STATE_DEFAULT); /* 只有左边有蓝色边框 */
/* 内边距 */
lv_obj_set_style_pad_all(card, 12, LV_STATE_DEFAULT);
/* 添加文字 */
lv_obj_t * label = lv_label_create(card);
lv_label_set_text(label, "温度: 26°C");
lv_obj_center(label);
这个卡片的效果是:白色背景,左边有一条2像素的蓝色竖线,文字居中。看起来非常清爽,适合做仪表盘上的数据卡片。
3.6 状态联动:边框与交互
边框在交互状态下的变化,是提升用户体验的关键。我建议你至少为以下状态设置不同的边框:
- 默认状态:浅色边框,宽度1~2像素
- 按下/选中状态:主题色边框,宽度2~3像素
- 禁用状态:灰色边框,透明度降低
/* 默认状态 */
lv_obj_set_style_border_width(btn, 1, LV_STATE_DEFAULT);
lv_obj_set_style_border_color(btn, lv_color_hex(0xCCCCCC), LV_STATE_DEFAULT);
/* 按下状态 */
lv_obj_set_style_border_width(btn, 2, LV_STATE_PRESSED);
lv_obj_set_style_border_color(btn, lv_color_hex(0x2196F3), LV_STATE_PRESSED);
你看,代码很简单,但效果立竿见影。用户按下去时,边框变粗、变色,反馈非常明确。
3.7 小结
边框属性这块,核心就记住三点:
- 宽度决定存在感——太细看不见,太粗显笨重
- 颜色和方向决定风格——单边边框更现代,全边框更传统
- 边框不占内容空间——别傻傻地去调尺寸
下一节我们会讲阴影和轮廓属性,这两个是「高级感」的关键。到时候我会分享一个我做车载HUD时用到的阴影技巧,保证让你眼前一亮。