3、样式属性详解(中):边框属性与轮廓属性

好,咱们接着聊样式属性。上一节我们把背景和渐变讲透了,这一节我重点说说边框和轮廓。这两个东西看着像,其实差别挺大。我在实际项目里见过不少新手把轮廓当边框用,结果布局全乱了。今天咱们就把它们彻底掰扯清楚。

3.1 边框属性(border)

边框,说白了就是控件的「外衣」。LVGL 的边框属性比你想的要丰富得多。它不只是画一条线那么简单,还涉及到颜色、宽度、圆角,甚至还有边距控制。

3.1.1 边框颜色(border_color)

这个最直观。设置边框颜色,用 lv_style_set_border_color() 就行。但我个人习惯,会先想清楚这个边框在 UI 里扮演什么角色。是强调?是分割?还是装饰?

lv_style_set_border_color(&style, lv_color_hex(0x2196F3));  // 蓝色边框

嗯,这里要注意:边框颜色默认是黑色。如果你不设置,它就会用黑色画一圈,很多时候会显得突兀。

3.1.2 边框宽度(border_width)

宽度决定了边框的「存在感」。1像素的边框很精致,3像素以上就有点「重」了。我做过一个工业控制面板的项目,客户要求按钮边框要 5 像素宽,结果整个界面看起来像儿童玩具。后来我建议改成 2 像素,配合圆角,效果立马就上来了。

lv_style_set_border_width(&style, 2);  // 2像素宽
小技巧:边框宽度为 0 时,边框不显示。但注意,这不会影响控件占用的空间。如果你想让控件「缩回去」,得配合 padding 调整。

3.1.3 边框圆角(border_radius)

圆角是 UI 美化的利器。LVGL 里用 border_radius 控制。值越大,角越圆。设置为控件高度的一半,就能得到一个圆形按钮。

lv_style_set_border_radius(&style, 10);  // 10像素圆角

我曾经遇到过一个坑:给一个矩形按钮设置了很大的圆角,结果里面的文字被裁掉了。为什么?因为圆角只影响边框的绘制,不影响内容区域。你想想看,内容区域还是原来的矩形,文字自然会被裁。解决办法是同时设置 pad_leftpad_right 等内边距,给文字留出空间。

注意:圆角值不要超过控件尺寸的一半。否则会出现「变形」现象,看起来很奇怪。

3.1.4 边框边距(border_side)

这个属性挺有意思。它控制边框画在哪几条边上。默认是四条边全画。但有时候我们只需要下边框,比如做一个分割线效果。

lv_style_set_border_side(&style, LV_BORDER_SIDE_BOTTOM);  // 只画下边框

可选的边有:

常量 说明
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.2 轮廓属性(outline)

轮廓和边框很像,但有一个关键区别:轮廓不占空间。它是在控件外部额外画的一圈线,不会影响布局。你想想看,这有什么用?

最常见的场景是焦点指示。当用户通过键盘或遥控器选中某个控件时,给它加一个轮廓,告诉用户「嘿,我在这儿」。边框也能做到,但边框会改变控件大小,导致布局抖动。轮廓就不会。

3.2.1 轮廓颜色(outline_color)

lv_style_set_outline_color(&style, lv_color_hex(0xFF9800));  // 橙色轮廓

我个人习惯用高亮色做轮廓,比如蓝色或橙色。这样用户一眼就能看到焦点在哪。

3.2.2 轮廓宽度(outline_width)

lv_style_set_outline_width(&style, 3);  // 3像素宽

轮廓宽度一般比边框宽一点,这样更醒目。但别太宽,否则会盖住旁边的控件。我曾经在一个密集的网格布局里用了 5 像素的轮廓,结果相邻控件的轮廓重叠了,看起来像连体婴儿。后来改成 2 像素就好了。

3.2.3 轮廓内边距(outline_pad)

这个属性控制轮廓离控件边缘的距离。正值会让轮廓往外扩,负值会让轮廓往里缩。

lv_style_set_outline_pad(&style, 5);  // 轮廓离控件边缘5像素

为什么要调这个?因为有时候轮廓太贴近控件,看起来像边框。稍微拉开一点距离,视觉效果会更清晰。我一般设 3 到 5 像素,既不会太远,也不会太近。

核心区别总结:
  • 边框:占用布局空间,影响控件大小。适合做永久性的装饰或分割。
  • 轮廓:不占空间,在控件外部绘制。适合做临时的焦点指示或高亮。

3.3 实战:做一个带焦点指示的按钮

光说不练假把式。咱们结合边框和轮廓,做一个实际例子。假设我们要做一个按钮,默认有细边框,获得焦点时显示粗轮廓。

/* 默认样式 */
lv_style_t style_btn;
lv_style_init(&style_btn);
lv_style_set_border_width(&style_btn, 1);
lv_style_set_border_color(&style_btn, lv_color_hex(0x999999));
lv_style_set_border_radius(&style_btn, 5);
lv_style_set_pad_all(&style_btn, 10);

/* 焦点样式 */
lv_style_t style_btn_focused;
lv_style_init(&style_btn_focused);
lv_style_set_outline_width(&style_btn_focused, 3);
lv_style_set_outline_color(&style_btn_focused, lv_color_hex(0x2196F3));
lv_style_set_outline_pad(&style_btn_focused, 3);

/* 创建按钮并添加样式 */
lv_obj_t *btn = lv_btn_create(lv_scr_act());
lv_obj_add_style(btn, &style_btn, 0);
lv_obj_add_style(btn, &style_btn_focused, LV_STATE_FOCUSED);

你看,这样当按钮获得焦点时,外面会多一圈蓝色轮廓,而按钮本身的大小不会变。用户体验会好很多。

避坑指南:我曾经在嵌入式设备上用过大的轮廓宽度,结果轮廓超出了屏幕边界,导致显示异常。所以记得检查轮廓是否会超出父控件的裁剪区域。如果父控件设置了 overflow: hidden,轮廓可能会被裁掉。

3.4 边框与轮廓的配合使用

在实际项目中,边框和轮廓经常一起用。比如一个卡片控件,用边框画出卡片边界,用轮廓表示选中状态。这样既保持了布局稳定,又实现了交互反馈。

嗯,这里再补充一点:轮廓的颜色和边框颜色最好有对比。如果两者颜色一样,用户可能分不清哪个是边框、哪个是轮廓。我一般会让轮廓颜色更亮或者饱和度更高。

好了,边框和轮廓就讲到这里。下一节咱们聊聊阴影和透明度,这两个属性能让你的 UI 瞬间「立体」起来。到时候见。