LVGL问题
本章目录
- 1. 页面出现花屏
- 2. 控件设置聚焦后,无法显示聚焦框
- 3. 控件设置了聚集后,仿真端能正常显示,但是在实际设备上无法显示
- 4. 下拉框设置了 Top 方向,但是下拉框的选项显示在了底部
- 5. 普通容器控件不需要能够滚动
- 6. 针对能够垂直滚动的容器控件,需要知道什么时候滚动到底部、顶部
- 7. 控件可以设置文本内容,但在样式里找不到字体设置
- 8. 控件设置 (0, 0) 位置后,但实际位置有偏移
- 9. 需要修改复选框的 □ 的大小
- 10. 加载新页面时,出现白屏
- 11. 给控件增加了Click事件,但是点击控件无法触发Click事件
- 12. 仿真程序预览时,聚焦控件会有外边框
本章正文
页面出现花屏
- 原因:页面透明度为
0
时,页面出现花屏。 - 解决方案:色彩深度LV_COLOR_DEPTH和LV_COLOR_SCREEN_TRANSP设置不一致,在
lv_conf.h
中设置一致。
16位色深时,如果需要页面透明度为0,需要将LV_COLOR_SCREEN_TRANSP设置为0,其他情况可以设置为1
#define LV_COLOR_DEPTH 16
#define LV_COLOR_SCREEN_TRANSP 0

控件设置聚焦后,无法显示聚焦框
- 原因:控件的聚焦框样式设置不正确。
- 解决方案:当控件处于聚焦状态时,使用的是模块
LV_PART_MAIN
状态LV_STATE_FOCUSED_KEY
的样式,所以只需要启用该样式,同时设置外边框的属性即可。

控件设置了聚集后,仿真端能正常显示,但是在实际设备上无法显示
- 原因:在设备初始化lvgl时,没有对
default_group
进行初始化,导致控件添加到default_group
失败。 - 解决方案:在设备初始化lvgl时,对
default_group
进行初始化。
提示
在初始化输入设备驱动,注册到lvgl时,可能需要将其分配到 default_group
中,在仿真端,已经注册了 鼠标
和 键盘
输入设备,同时分配到了 default_group
中,所以在仿真端上,能够通过 鼠标滚轮
和 键盘Tab键
来切换控件的聚焦状态。
//检查默认组是否创建
if (lv_group_get_default() == NULL) {
// 创建并设置默认组
lv_group_t *default_group = lv_group_create();
lv_group_set_default(default_group);
}
下拉框设置了 Top
方向,但是下拉框的选项显示在了底部
- 原因:下拉框的选项高度过高,无法完全显示在顶部,控件内部将其修改显示在了底部。
- 解决方法:调整下拉框的选项高度,使其能够完全显示在顶部。
普通容器控件不需要能够滚动
- 原因:容器控件默认有
ScrollAble
(LV_OBJ_FLAG_SCROLLABLE) 标识,当容器控件里面的子控件超出容器控件的大小时,这时候容器控件可以滚动。 - 解决方法:
清除
容器控件的ScrollAble
标识。
针对能够垂直滚动的容器控件,需要知道什么时候滚动到底部、顶部
- 解决方法:通过设置容器控件的
LV_EVENT_SCROLL_END
事件,在事件回调里判断是否滚动到底部、顶部。
lv_obj_t * src = lv_event_get_target(e);
lv_coord_t bottom = lv_obj_get_scroll_bottom(src);
lv_coord_t top = lv_obj_get_scroll_top(src);
//获取子对象中最小的y1坐标
lv_coord_t minChildY1 = LV_COORD_MAX;
int32_t cnt = lv_obj_get_child_cnt(src);
for (int32_t i = 0; i < cnt; i++) {
lv_obj_t * child = lv_obj_get_child(src, i);
if (child && lv_obj_has_flag(child, LV_OBJ_FLAG_HIDDEN) == false) {
lv_coord_t y = lv_obj_get_y(child);
minChildY1 = LV_MIN(minChildY1, y);
}
}
if (bottom == 0) { //因为子控件中最大的y2坐标从滚动视图的底部开始计算,所以当bottom为0时,说明滚动到了底部
LV_LOG_WARN("scroll to bottom");
} else if (top == minChildY1) { //当top等于子控件中最小的y1坐标时,说明滚动到了顶部
LV_LOG_WARN("scroll to top");
}

控件可以设置文本内容,但在样式里找不到字体设置
- 原因:一些简单文本控件,如
标签
、按钮
、输入框
等,字体在LV_PART_MAIN
模块下进行设置,但有些控件,并不是在LV_PART_MAIN
模块下设置字体,如下拉框
的下拉列表
部分,是在LV_DROPDOWN_PART_LIST
模块下设置字体。 - 解决方法:在控件的样式中,找到对应的模块,进行字体设置。
控件设置 (0, 0) 位置后,但实际位置有偏移
- 原因:当父控件的
border_width
、padding_left
、padding_top
不为0时,控件设置 (0, 0) 位置后,实际位置会向右下角偏移。 - 解决方法:将父控件的
border_width
、padding_left
、padding_top
设置为0。
// 这个函数说明了控件的内容大小是会减去 `border_width` 和 `padding` 的,这也是父控件 `border_width` 和 `padding` 会影响子控件位置的原因。
void lv_obj_get_content_coords(const lv_obj_t * obj, lv_area_t * area)
{
LV_ASSERT_OBJ(obj, MY_CLASS);
lv_coord_t border_width = lv_obj_get_style_border_width(obj, LV_PART_MAIN);
lv_obj_get_coords(obj, area);
lv_area_increase(area, -border_width, -border_width);
area->x1 += lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
area->x2 -= lv_obj_get_style_pad_right(obj, LV_PART_MAIN);
area->y1 += lv_obj_get_style_pad_top(obj, LV_PART_MAIN);
area->y2 -= lv_obj_get_style_pad_bottom(obj, LV_PART_MAIN);
}

需要修改复选框的 □
的大小
- 解决方法:通过修改复选框的样式,设置字体的大小,来实现修改
□
的大小。

加载新页面时,出现白屏
- 原因:在加载页面时,勾选了
加载新屏幕前释放当前屏幕内存
,同时动画时长
不为0,加载新页面前,当前页面下的控件都已经被释放,同时页面背景颜色为白色,所以在加载新页面完成前,显示的那一刻,会出现白屏。 - 解决方法:将
加载新屏幕前释放当前屏幕内存
的选项取消勾选,或者将动画时长
设置为0。
提示
勾选了 删除当前页面
,则会在加载新页面后,删除旧页面(包括旧页面下的控件)
给控件增加了Click事件,但是点击控件无法触发Click事件
- 原因:控件的没有
LV_OBJ_FLAG_CLICKABLE
标识,导致无法触发Click事件。 - 解决方法:给控件添加
LV_OBJ_FLAG_CLICKABLE
标识。
提示
默认没有 LV_OBJ_FLAG_CLICKABLE
标识的控件类型:图片、标签、直线、加载、GIF、视频、Lottie动画、帧动画、画布、进度文本
仿真程序预览时,聚焦控件会有外边框
- 原因:在仿真程序启动时,系统会自动将焦点设置到第一个可以接收焦点的控件上。当控件获得焦点时,为了突出显示,
LVGL
默认主题会给一些控件类型的LV_STATE_FOCUSED_KEY
状态,添加一个外边框(outline)。其目的是让用户知道哪个控件当前处于活动状态。 - 解决方法:如果不想显示这个外边框,可以修改
lv_theme_default.c
文件,找到outline_primary
样式的定义,并将其相关设置注释掉,这样就能去除聚焦时的外边框效果。
// 在 lv_theme_default.c 中,找到 outline_primary 样式相关设置,注释掉
style_init_reset(&styles->outline_primary);
// lv_style_set_outline_color(&styles->outline_primary, theme.color_primary);
// lv_style_set_outline_width(&styles->outline_primary, OUTLINE_WIDTH);
// lv_style_set_outline_pad(&styles->outline_primary, OUTLINE_WIDTH);
// lv_style_set_outline_opa(&styles->outline_primary, LV_OPA_50);