基础

  • LVGL只使用一个线程,运行一个定时器程序,这个程序会定期执行所注册的回调函数,达到更新和渲染的作用
  • 注册到LVGL的回调函数叫做“任务”(与RTOS中不同)
  • 裁剪LVGL
  • 在lv_conf.h中进行裁剪

控件概述

  • UI树:树中的所有控件都是obj,根控件是“屏幕”

  • 基础对象obj

  • 大小、位置、字体、颜色、背景颜色、透明度、盒子模型:lv_obj_set_XXX()

  • 一次性父对齐:lv_obj_set_align()

  • 永久父对齐:lv_obj_align()
  • 永久指定对象对齐:lv_obj_align_to()
  • 永久内部控件对齐:lv_obj_set_style_align()

  • 本地样式:lv_obj_set_style_STYLE()

    • 支持选择器
  • 共享样式:lv_obj_add_style()

    • 创建共享样式:先style_init(),再lv_style_set_STYLE()
    • 样式保存的地址必须是持久的,比如静态全局/静态局部/动态分配,但不能是普通局部变量
    • 支持选择器
  • 事件:lv_obj_add_event()

    • 手动发送事件:lv_event_send()
    • 获取事件:lv_event_get_XXX()
    • 支持选择器
  • 状态:lv_obj_add_state()
    • 获取状态:lv_obj_has_state()
    • 支持选择器
  • 宏开关:lv_obj_add_flag()

  • 选择器:多个LV_STATE选择器 | 一个LV_PART选择器,可对“处于STATE状态的PART部分”进行修改

  • 一般控件

  • 创建特定类型的控件:lv_TYPE_create(PARENT)
  • 控件类型:obj控件(矩形)、btn控件、switch控件等

  • 屏幕控件

  • 没有父节点,一个物理显示器可以有多个屏幕
    • 创建屏幕:lv_obj_create(NULL)
    • 获取屏幕:lv_screen_active()
  • 一个屏幕初始有顶层和系统层
    • 获取层:lv_layer_top()/lv_layer_sys()

控件

  • 宏开关
  • CLICKABLE:使控件可触发点击事件
  • CHECKABLE:使控件可触发切换状态事件(切换后会保持状态值)
  • 回调函数
  • 控件树冒泡机制

    • 遍历(搜索):UI树根节点->...->父结点->绑定了回调的结点
    • 冒泡(回溯):绑定了回调的结点->父结点->...->UI树根节点
  • lv_event_get_code():获取触发事件

  • lv_event_get_target():获取触发源

    • 若存在:屏幕->绑定了回调的Button,则触发时返回Button
  • lv_event_get_current_target():获取当前搜索/冒泡到的结点

    • 若存在:屏幕->绑定了回调的Button,则触发时会返回Srceen(因为触发完就向上冒泡了)
    • 若存在:屏幕->绑定了回调的Msgbox->绑定了回调的ButtonMatrix,则触发时会返回ButtonMatrix

文本与图像

  • label
  • recolor开启部分着色模式
  • long_mode开启长文本模式
  • 可以使用LV_SYMBOL来显示图标
  • img
  • recolor开启部分着色模式
  • 可以设置图片源的像素数组,由Image Converter — LVGL进行生成,然后用LV_IMG_DECLARE()导入到代码
  • 可以设置带ALPHA图片的背景颜色和透明度
  • 可以设置图片偏移、旋转、放大、中心点
    • 必须先图片布局信息,再设置中心点
  • 可以使用LV_SYMBOL_DUMMY来显示文本
  • spinbox
  • 可以设置范围、步进值、当前值、数字格式和光标
  • 可以递增/递减

按钮

  • button
  • btnmatrix
  • 使用字符串数组来设置矩阵文本和宽高
  • 可以设置按钮的相对宽度(即比例)、属性、单次选中功能
  • imgbutton
  • 按钮分为左中右三个区域,对每个部分可以设置图片源
  • 由于三个区域的各自宽度!=按钮宽度/3,而是等于各自的图片宽度,所以如果按钮太小会导致图片显示不全
  • switch
  • checkbox
  • led
  • 可以设置led颜色、亮度(是led专有的函数)
  • 可以打开、关闭、翻转(本质是设置led颜色)
  • 如果设置led颜色/开关led只让边框变色,那么可以结合设置obj颜色来解决问题

控件条

  • bar
  • 可以设置范围、当前值,每次设置当前值就会更新进度条
    • 配合定时器来实现定时更新,配合动画来实现每次更新的过渡动画
    • 一般动画时长=定时器更新时长,使得动画过渡完就可以更新
  • 可以设置bar的模式(非NORMAL模式支持非零起始值)
  • spinner
  • slider
  • 可以设置范围、当前值
  • 可以设置slider的模式(非NORMAL模式支持左值和右值)
  • arc

组件列表

  • list
  • 可以使用LV_SYMBOL作为列表按钮的图标
  • dropdown
  • 使用“a\nb\nc”字符串来设置三个选项a、b、c
  • 可以使用LV_SYMBOL作为下拉框按钮的图标
  • 可以设置下拉框的展示方向
  • roller
  • 使用“a\nb\nc”字符串来设置三个选项a、b、c
  • 可以设置滚动模式、滚轮区域行数

绘图

  • line
  • 使用数组输入line的坐标点
  • 可以设置坐标轴反转

输入

  • textarea
  • 可以增删字符、文本,可以设置占位符
  • 可以设置光标位置、文本框模式、输入限制
  • keyboard
  • 可以关联textarea
  • 可以设置按键弹窗
  • 可以设置键盘模式

窗口控件

  • tabview

  • 无法使用PART直接获取部分,只能用getter

  • 可以设置选项栏摆放位置和大小

  • 可以添加tab,并在tab中设置内容(即把tab作为父节点)

  • tileview

  • 无法使用PART直接获取部分,只能用getter

  • 可以设置滑动方向
  • 可以添加tile(给出列和行),并在tile中设置内容(即把tile作为父节点)

  • win

  • 无法使用PART直接获取部分,只能用getter

  • 可以设置窗口图标、标题、按钮(按钮放在标题前后的效果不同)
  • 可以获取主体后,在主体中设置内容(即把它作为父节点)

  • msgbox

  • 无法使用PART直接获取部分,只能用getter

  • 模态弹窗:如果父元素为NULL,则此时将msgbox作为屏幕(根结点),因此不可操作msgbox以外的控件
  • 非模态弹窗:反之则可以
  • 可以设置标题、文本等
  • 可以添加Header/Footer按钮(一次添加一个,可添加多个)
  • 可以同步关闭弹窗(直接关闭)/异步关闭弹窗(下一次重新打开弹窗时才关闭,连续打开-关闭弹窗时使用)

  • table

  • 设置行列数、列宽

  • 设置单元格内容

布局

  • Flex:沿主轴(默认从上到下)和交叉轴(默认从左到右)排列控件

  • 可以设置主轴对齐方式、交叉轴对齐方式

  • 可以设置行/列的摆放比例(叫做flex grow)

  • Grid

定时器

  • 定时器使用lv_timer_handler来计时
  • 启用/禁用、准备、重置、暂停/恢复
  • 设置定时回调函数、恢复回调函数、重复次数
  • 可以测量lv_timer_handler的空闲时间(而不是整个系统的空闲时间)
  • 可以异步调用函数:参数必须持久化

动画

  • 假设有一个控件w,需要用动画调用lv_obj_set_x()来修改控件w的x属性
  • 则动画的变量 = 控件w
  • 则动画的回调函数 = lv_obj_set_x()
  • 则动画的动画轨迹函数 = lv_anim_path_linear()之类的轨迹函数
  • 使用步骤
  • 创建一个lv_anim_t类型的动画变量a,并使用anim_init(&a)初始化
  • 设置a的变量、回调函数、动画轨迹函数
  • 设置动画时间或速度、动画的初始值和最终值
  • 设置动画特性:倒放、某个阶段的回调函数、某个阶段的delay时间、重复
  • 使用lv_anim_start(&a)启动动画

页面切换

三种切换方式(A->B)

  • 隐藏并覆盖
  • 准备两个页面A、B:均属于一颗UI树(继承于同一个屏幕根结点)
  • page_A:lv_obj_add_flag(obj, LV_OBJ_FLAG_HIDDEN)
  • page_B:lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN)
  • 保留并切换
  • 准备两个页面A、B:属于同一个或者不同的UI树
  • page_A
    • 将page_A插入全局页面栈链表(用于FIFO式的页面返回)
    • 若(page_B!=NULL)
    • 则调用lv_scr_load_anim()或者lv_scr_load()
  • 删除并切换
  • page_A
    • 若(page_B!=NULL && current_screen != page_A)
    • 则调用lv_scr_load_anim()或者lv_scr_load()
    • 并且lv_obj_del(current_screen);