3. 标签控件(lv_label):文本显示与换行、长文本模式、对齐与颜色

标签控件,说白了就是屏幕上显示文字的那个东西。在 LVGL 里,lv_label 是最基础、最常用的控件之一。你做的任何一个界面,几乎都离不开它。

我个人习惯把标签控件比作「一张白纸」。你可以往上面写字,可以控制字怎么写、写不下怎么办、字靠左还是靠右。今天我们就把它彻底讲透。

核心要点:lv_label 的本质是文本容器,所有显示效果都围绕「文本内容 + 显示模式 + 样式属性」这三个维度展开。

3.1 创建与基本文本显示

创建一个标签非常简单。先看代码:

/* 创建标签 */
lv_obj_t * label = lv_label_create(lv_scr_act());

/* 设置文本 */
lv_label_set_text(label, "Hello, LVGL!");

/* 设置位置 */
lv_obj_set_pos(label, 10, 10);

嗯,这里要注意:lv_label_set_text() 会复制你传入的字符串。如果你频繁更新文本,建议用 lv_label_set_text_fmt() 做格式化,或者用 lv_label_set_text_static() 避免内存拷贝。

我的习惯:静态文本(比如界面标题)用 lv_label_set_text_static(),动态文本(比如传感器读数)用 lv_label_set_text_fmt()。前者省内存,后者方便拼接。

3.2 文本换行:长句子的处理

如果你只是设了一行文字,那很简单。但实际项目中,文本经常超出屏幕宽度。这时候就需要换行。

LVGL 提供了两种换行方式:

模式 宏定义 行为
自动换行 LV_LABEL_LONG_WRAP 根据标签宽度自动折行,单词不断开
手动换行 文本中插入 \n 强制在指定位置换行

举个例子:

/* 自动换行模式 */
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_set_width(label, 120);  /* 限制宽度 */
lv_label_set_text(label, "这是一段比较长的文本,看看它怎么自动换行。");

/* 手动换行 */
lv_label_set_text(label, "第一行\n第二行\n第三行");

我在项目中遇到过一个问题:自动换行时,如果文本里包含很长的英文单词或 URL,它不会在单词中间断开。结果就是那个单词直接溢出。解决办法?要么手动加 \n,要么改用裁剪模式。

避坑指南:我曾经在显示 Wi-Fi 密码时用了自动换行,结果密码里的连字符被当成单词的一部分,排版全乱了。后来我改用 LV_LABEL_LONG_DOT 模式,超出部分显示省略号,用户点击后再弹出完整密码。体验好很多。

3.3 长文本模式:滚动、裁剪与扩展

文本太长,屏幕放不下,怎么办?LVGL 给了你四种选择。我画了一张图帮你理解:

长文本模式对比 LV_LABEL_LONG_CROP 超出部分直接裁剪掉 LV_LABEL_LONG_SCROLL 水平滚动显示全部文本 LV_LABEL_LONG_SCROLL_CIRC 循环滚动,像跑马灯 LV_LABEL_LONG_DOT 超出部分显示 ... LV_LABEL_LONG_EXPAND 自动扩展标签宽度 💡 选型建议 • 静态提示文字 → 裁剪或省略号 • 动态消息/歌词 → 滚动或循环滚动

具体用法:

/* 裁剪模式:超出部分直接看不见 */
lv_label_set_long_mode(label, LV_LABEL_LONG_CROP);

/* 滚动模式:文本会水平滚动 */
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL);

/* 循环滚动:像跑马灯一样循环 */
lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRC);

/* 省略号模式:超出部分显示 ... */
lv_label_set_long_mode(label, LV_LABEL_LONG_DOT);

/* 扩展模式:标签宽度自动撑开 */
lv_label_set_long_mode(label, LV_LABEL_LONG_EXPAND);
我的经验:滚动模式默认只在文本超出时才滚动。如果你想让短文本也滚动,可以设置 lv_obj_set_width(label, 50) 强制缩小宽度。另外,循环滚动适合做通知条或歌词显示,但别用在按钮上——用户会晕。

3.4 文本对齐:左、中、右

对齐方式影响的是多行文本的排列。单行文本无所谓对齐,因为就一行。但多行时,对齐就很重要了。

对齐方式 宏定义 效果
左对齐 LV_TEXT_ALIGN_LEFT 每行文字左边缘对齐(默认)
居中对齐 LV_TEXT_ALIGN_CENTER 每行文字居中对齐
右对齐 LV_TEXT_ALIGN_RIGHT 每行文字右边缘对齐
/* 设置对齐方式 */
lv_label_set_text(label, "第一行\n第二行\n第三行");

/* 左对齐(默认) */
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_LEFT, 0);

/* 居中对齐 */
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0);

/* 右对齐 */
lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_RIGHT, 0);

你想想看,如果显示一个弹窗标题,居中对齐是不是更舒服?如果显示一个列表项,左对齐更自然。右对齐嘛,我一般用在数字或金额的显示上,方便对比个十百千位。

注意:对齐方式只对多行文本有效。单行文本无论你怎么设对齐,看起来都一样。另外,对齐是样式属性,不是标签模式,所以用 lv_obj_set_style_text_align() 来设置。

3.5 文本颜色与样式

颜色设置也是通过样式完成的。你可以设置文字颜色、背景色、透明度等。

/* 设置文字颜色为红色 */
lv_obj_set_style_text_color(label, lv_color_hex(0xFF0000), 0);

/* 设置文字透明度 */
lv_obj_set_style_text_opa(label, LV_OPA_50, 0);  /* 50% 透明 */

/* 设置文字字体 */
lv_obj_set_style_text_font(label, &lv_font_montserrat_20, 0);

/* 设置文字背景色(仅文字区域) */
lv_obj_set_style_text_bg_color(label, lv_color_hex(0xFFFF00), 0);

这里有个细节:lv_color_hex() 的参数是 16 进制 RGB 值,比如 0xFF0000 是红色。如果你需要带透明度,用 lv_color_hex32(),格式是 0xAARRGGBB,AA 是透明度。

实用技巧:我经常用 lv_obj_set_style_text_color() 配合状态变化。比如按钮按下时文字变灰,松开后恢复。这样用户交互反馈就很直观。

3.6 综合示例:一个带滚动和颜色的通知条

最后,我们做一个实际的小例子。一个通知条,文字太长时循环滚动,文字颜色是蓝色,背景半透明。

/* 创建标签 */
lv_obj_t * notify = lv_label_create(lv_scr_act());
lv_obj_set_size(notify, 200, 30);
lv_obj_center(notify);

/* 设置长文本模式为循环滚动 */
lv_label_set_long_mode(notify, LV_LABEL_LONG_SCROLL_CIRC);

/* 设置文本 */
lv_label_set_text(notify, "系统通知:检测到新版本 v2.1.0,请及时更新。");

/* 设置文字颜色为蓝色 */
lv_obj_set_style_text_color(notify, lv_color_hex(0x2196F3), 0);

/* 设置背景色为浅灰色,半透明 */
lv_obj_set_style_bg_color(notify, lv_color_hex(0xEEEEEE), 0);
lv_obj_set_style_bg_opa(notify, LV_OPA_80, 0);

/* 设置圆角 */
lv_obj_set_style_radius(notify, 5, 0);

这段代码跑起来,你会看到一个浅灰底色的通知条,蓝色文字从左到右循环滚动。嗯,这就是实际项目中很常见的「跑马灯通知」效果。

最后说一句:标签控件虽然简单,但用好它需要理解「文本内容 → 显示模式 → 样式属性」这条链路。我在做嵌入式界面时,80% 的文本显示问题都出在这三个环节的配合上。你只要把今天讲的这几个模式试一遍,基本就能应对绝大多数场景了。