Skip to content

基础部件

编程思想

使用的是面向对象的编程思想, 以抽象的类实现不同的部件

使用lv_obj_t这一个类实例化出来一个lv_obj类, 之后使用这一个类衍生出来其他的类(开关, 标签, 滑块)

lvgl在初始化的时候会创建一个活动屏幕对象, 可以使用lv_scr_act这一个函数获取这一个对象

c
lv_obj_t * switch_obj = lv_switch_create(lv_scr_act()); //创建一个对象, 绑定父对象
lv_obj_set_size(switch_obj, 120, 60);
lv_obj_align(switch_obj, LV_ALIGN_CENTER, 0, 0);

默认创建的对象是在父对象的左上角

c
    lv_obj_t * switch_obj = lv_switch_create(lv_scr_act());
    lv_obj_set_size(switch_obj, 120, 60);
    lv_obj_t * switch_obj2 = lv_switch_create(switch_obj);

image-20240527233403402

基础对象

可以作为一个父对象创建其他的对象, 也可以作为一个部件进行使用, 创建其他的对象的时候, 默认使用活动屏幕作为父对象(基础对象)

image-20240528091728016

image-20240528092031458

c
lv_obj_t *obj = lv_obj_create(lv_scr_act());

父对象和子对象的关系

  1. 子对象会随着父对象进行移动
  2. 子对象超出父对象的位置不会进行显示

image-20240528092734865

基本对象的属性

c
typedef struct _lv_obj_t {
    const lv_obj_class_t * class_p;
    struct _lv_obj_t * parent;
    _lv_obj_spec_attr_t * spec_attr;
    _lv_obj_style_t * styles;
#if LV_USE_USER_DATA
    void * user_data;
#endif
    lv_area_t coords;
    lv_obj_flag_t flags;
    lv_state_t state;
    uint16_t layout_inv : 1;
    uint16_t scr_layout_inv : 1;
    uint16_t skip_trans : 1;
    uint16_t style_cnt  : 6;
    uint16_t h_layout   : 1;
    uint16_t w_layout   : 1;
} lv_obj_t;

基本属性为

  • 大小
  • 位置
  • 对齐
  • 样式
  • 事件

大小

c
void lv_obj_set_width(lv_obj_t * obj, lv_coord_t w);
void lv_obj_set_height(lv_obj_t * obj, lv_coord_t h);
void lv_obj_set_size(lv_obj_t * obj, lv_coord_t w, lv_coord_t h)

位置

设置子对象的位置的时候, 左边原点是在父对象的左上角

c
void lv_obj_set_x(lv_obj_t * obj, lv_coord_t x);
void lv_obj_set_y(lv_obj_t * obj, lv_coord_t y);
void lv_obj_set_pos(lv_obj_t * obj, lv_coord_t x, lv_coord_t y);

对齐

  1. 参照父对象进行对齐(不可以超出父对象)
  2. 参照其他的对象进行对齐
c
void lv_obj_set_align(lv_obj_t * obj, lv_align_t align);
void lv_obj_align(lv_obj_t * obj, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs);

相对于父对象, 两种, 第二种在对齐的同时可以设置一个偏移

c
void lv_obj_align_to(lv_obj_t * obj, const lv_obj_t * base, lv_align_t align, lv_coord_t x_ofs, lv_coord_t y_ofs)

参照其他的对象, 不需要有父子关系

image-20240528100929315

c
lv_obj_t *obj = lv_obj_create(lv_scr_act());
lv_obj_set_align(obj, LV_ALIGN_CENTER);

子对象设置的时候不可以设置在外面, 没有父子关系的时候可以随意设置

在使用对齐的时候子对象需要考虑主屏幕的范围, 当两个变量宽度使用的时候外部对齐的下面三个实际的样式是一样的

image-20240528101048804

样式

用于设置一个部件的外观, 优化显示的界面以及和用户进行交互

如何添加

  • 添加普通的样式
c
    static lv_style_t style; //这一个一定要是一个静态的变量
    lv_style_init(&style);
    lv_style_set_bg_color(&style, lv_color_hex(0xf4b183)); //设置背景颜色

    lv_obj_t *obj = lv_obj_create(lv_scr_act());
    lv_obj_add_style(obj, &style, LV_STATE_DEFAULT); //设置部件的样式, 第三个参数是什么状态的时候触发, 以及应用的部分

image-20240528123057321

  • 添加一个本地的样式
c
lv_obj_t *obj = lv_obj_create(lv_scr_act());
lv_obj_set_style_bg_color(obj, lv_color_hex(0xf4b183), LV_PART_MAIN);

生效的时间

c
enum {
    LV_STATE_DEFAULT     =  0x0000, //默认状态
    LV_STATE_CHECKED     =  0x0001, //切换或者选中模式
    LV_STATE_FOCUSED     =  0x0002, //通过键盘, 编码器聚焦或通过触摸板鼠标单击
    LV_STATE_FOCUS_KEY   =  0x0004, //键盘, 编码器聚焦
    LV_STATE_EDITED      =  0x0008, //编码器编辑
    LV_STATE_HOVERED     =  0x0010, //鼠标悬停
    LV_STATE_PRESSED     =  0x0020, //已按下
    LV_STATE_SCROLLED    =  0x0040, //滚动状态
    LV_STATE_DISABLED    =  0x0080, //禁用状态

    LV_STATE_USER_1      =  0x1000,
    LV_STATE_USER_2      =  0x2000,
    LV_STATE_USER_3      =  0x4000,
    LV_STATE_USER_4      =  0x8000,

    LV_STATE_ANY = 0xFFFF,    /**< Special value can be used in some functions to target all states*/
};

这里的状态有的需要进行添加

c
void lv_obj_add_state(lv_obj_t * obj, lv_state_t state);
void lv_obj_clear_state(lv_obj_t * obj, lv_state_t state)

有的属性

c
void lv_style_set_width(lv_style_t * style, lv_coord_t value); //宽度
void lv_style_set_min_width(lv_style_t * style, lv_coord_t value);
void lv_style_set_max_width(lv_style_t * style, lv_coord_t value);
void lv_style_set_height(lv_style_t * style, lv_coord_t value);
void lv_style_set_min_height(lv_style_t * style, lv_coord_t value); //最大值
void lv_style_set_max_height(lv_style_t * style, lv_coord_t value);
void lv_style_set_x(lv_style_t * style, lv_coord_t value); //设置位置
void lv_style_set_y(lv_style_t * style, lv_coord_t value);
void lv_style_set_align(lv_style_t * style, lv_align_t value); //对齐
void lv_style_set_transform_width(lv_style_t * style, lv_coord_t value); //两遍同时变宽
void lv_style_set_transform_height(lv_style_t * style, lv_coord_t value); //同时变高
void lv_style_set_translate_x(lv_style_t * style, lv_coord_t value);  //基于现有的位置移动
void lv_style_set_translate_y(lv_style_t * style, lv_coord_t value);
void lv_style_set_transform_zoom(lv_style_t * style, lv_coord_t value); //缩放, 256为不缩放
void lv_style_set_transform_angle(lv_style_t * style, lv_coord_t value); //旋转角度 = 旋转值 / 10
void lv_style_set_pad_top(lv_style_t * style, lv_coord_t value); //填充属性, 设置和父对象的距离
void lv_style_set_pad_bottom(lv_style_t * style, lv_coord_t value);
void lv_style_set_pad_left(lv_style_t * style, lv_coord_t value);
void lv_style_set_pad_right(lv_style_t * style, lv_coord_t value);
void lv_style_set_pad_row(lv_style_t * style, lv_coord_t value); //行列填充, 布局使用
void lv_style_set_pad_column(lv_style_t * style, lv_coord_t value); //栏间距
void lv_style_set_bg_color(lv_style_t * style, lv_color_t value); //背景颜色
void lv_style_set_bg_color_filtered(lv_style_t * style, lv_color_t value); //背景过滤颜色
void lv_style_set_bg_opa(lv_style_t * style, lv_opa_t value); //背景透明度
void lv_style_set_bg_grad_color(lv_style_t * style, lv_color_t value); //背景颜色渐变
void lv_style_set_bg_grad_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_bg_grad_dir(lv_style_t * style, lv_grad_dir_t value); //设置渐变的方向
void lv_style_set_bg_main_stop(lv_style_t * style, lv_coord_t value); //设置渐变的起始位置, 0-255
void lv_style_set_bg_grad_stop(lv_style_t * style, lv_coord_t value); //设置渐变的终点
void lv_style_set_bg_grad(lv_style_t * style, const lv_grad_dsc_t * value);
void lv_style_set_bg_dither_mode(lv_style_t * style, lv_dither_mode_t value);
void lv_style_set_bg_img_src(lv_style_t * style, const void * value); //背景图片
void lv_style_set_bg_img_opa(lv_style_t * style, lv_opa_t value); //背景图片的透明度
void lv_style_set_bg_img_recolor(lv_style_t * style, lv_color_t value);  //背景图片重新着色, 默认透明
void lv_style_set_bg_img_recolor_filtered(lv_style_t * style, lv_color_t value); 
void lv_style_set_bg_img_recolor_opa(lv_style_t * style, lv_opa_t value); //设置着色的透明度
void lv_style_set_bg_img_tiled(lv_style_t * style, bool value); //背景图片平铺(这一个图片重复并覆盖背景)
void lv_style_set_border_color(lv_style_t * style, lv_color_t value); //边框颜色
void lv_style_set_border_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_border_opa(lv_style_t * style, lv_opa_t value); //边框透明度
void lv_style_set_border_width(lv_style_t * style, lv_coord_t value); //边框的宽度
void lv_style_set_border_side(lv_style_t * style, lv_border_side_t value); //边框的边的选择
void lv_style_set_border_post(lv_style_t * style, bool value); // 设置边框和子对象的绘制顺序
void lv_style_set_outline_width(lv_style_t * style, lv_coord_t value); // 轮廓的宽度
void lv_style_set_outline_color(lv_style_t * style, lv_color_t value); //轮廓的颜色
void lv_style_set_outline_color_filtered(lv_style_t * style, lv_color_t value); 
void lv_style_set_outline_opa(lv_style_t * style, lv_opa_t value); //轮廓的透明度
void lv_style_set_outline_pad(lv_style_t * style, lv_coord_t value); //轮廓的间隙属性
void lv_style_set_shadow_width(lv_style_t * style, lv_coord_t value); //阴影属性
void lv_style_set_shadow_ofs_x(lv_style_t * style, lv_coord_t value); //阴影在x轴的偏移
void lv_style_set_shadow_ofs_y(lv_style_t * style, lv_coord_t value); //阴影在y轴的偏移
void lv_style_set_shadow_spread(lv_style_t * style, lv_coord_t value); //扩展
void lv_style_set_shadow_color(lv_style_t * style, lv_color_t value); //颜色
void lv_style_set_shadow_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_shadow_opa(lv_style_t * style, lv_opa_t value); //透明度
void lv_style_set_img_opa(lv_style_t * style, lv_opa_t value); //透明度
void lv_style_set_img_recolor(lv_style_t * style, lv_color_t value); //重新着色
void lv_style_set_img_recolor_filtered(lv_style_t * style, lv_color_t value); 
void lv_style_set_img_recolor_opa(lv_style_t * style, lv_opa_t value); //透明度 
void lv_style_set_line_width(lv_style_t * style, lv_coord_t value); //线条的宽度
void lv_style_set_line_dash_width(lv_style_t * style, lv_coord_t value); //线条的端点的属性
void lv_style_set_line_dash_gap(lv_style_t * style, lv_coord_t value); //设置虚线的宽度
void lv_style_set_line_rounded(lv_style_t * style, bool value); //线的头部
void lv_style_set_line_color(lv_style_t * style, lv_color_t value); //线的颜色
void lv_style_set_line_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_line_opa(lv_style_t * style, lv_opa_t value); //线的透明度
void lv_style_set_arc_width(lv_style_t * style, lv_coord_t value); //圆弧的宽度
void lv_style_set_arc_rounded(lv_style_t * style, bool value); //圆弧的头部是不是圆头
void lv_style_set_arc_color(lv_style_t * style, lv_color_t value); //设置颜色
void lv_style_set_arc_color_filtered(lv_style_t * style, lv_color_t value); 
void lv_style_set_arc_opa(lv_style_t * style, lv_opa_t value); //透明度
void lv_style_set_arc_img_src(lv_style_t * style, const void * value);
void lv_style_set_text_color(lv_style_t * style, lv_color_t value); //文本
void lv_style_set_text_color_filtered(lv_style_t * style, lv_color_t value);
void lv_style_set_text_opa(lv_style_t * style, lv_opa_t value);
void lv_style_set_text_font(lv_style_t * style, const lv_font_t * value); //设置字体
void lv_style_set_text_letter_space(lv_style_t * style, lv_coord_t value); //文本间的间隙
void lv_style_set_text_line_space(lv_style_t * style, lv_coord_t value); //行间距
void lv_style_set_text_decor(lv_style_t * style, lv_text_decor_t value); //设置下划线的删除
void lv_style_set_text_align(lv_style_t * style, lv_text_align_t value); //设置对齐属性
void lv_style_set_radius(lv_style_t * style, lv_coord_t value); //圆角的属性
void lv_style_set_clip_corner(lv_style_t * style, bool value); //吧圆角上的元素剪切
void lv_style_set_opa(lv_style_t * style, lv_opa_t value); //透明度
void lv_style_set_color_filter_dsc(lv_style_t * style, const lv_color_filter_dsc_t * value); //填充颜色
void lv_style_set_color_filter_opa(lv_style_t * style, lv_opa_t value); 
void lv_style_set_anim_time(lv_style_t * style, uint32_t value); //动画
void lv_style_set_anim_speed(lv_style_t * style, uint32_t value);
void lv_style_set_transition(lv_style_t * style, const lv_style_transition_dsc_t * value); //设置过渡
void lv_style_set_blend_mode(lv_style_t * style, lv_blend_mode_t value); //混合模式
void lv_style_set_layout(lv_style_t * style, uint16_t value); //布局
void lv_style_set_base_dir(lv_style_t * style, lv_base_dir_t value); //设置方向

Style properties — LVGL documentation

  • size 大小
  • position 位置
  • background 背景
  • outline 轮廓
  • border 边框
  • shadow 阴影
  • others 其他

image-20240528131108181

边框

c
lv_obj_t *obj = lv_obj_create(lv_scr_act());
lv_obj_set_align(obj, LV_ALIGN_CENTER);
lv_obj_set_style_border_color(obj, lv_color_hex(0x2580FF), LV_STATE_DEFAULT);

image-20240528131324808

c
lv_obj_set_style_border_width(obj, 6, LV_STATE_DEFAULT); //边框宽度
lv_obj_set_style_border_opa(obj, LV_OPA_20, LV_STATE_DEFAULT); //边框透明度, 0-255, 宏是百分比

image-20240528131659042

c
lv_obj_set_style_border_color(obj, lv_color_hex(0x2580FF), LV_STATE_DEFAULT);
lv_obj_set_style_border_width(obj, 6, LV_STATE_DEFAULT); //边框宽度
lv_obj_set_style_border_opa(obj, LV_OPA_20, LV_STATE_DEFAULT); //边框透明度, 0-255, 宏是百分比
lv_obj_set_style_outline_color(obj, lv_color_hex(0x005312), LV_STATE_DEFAULT);
lv_obj_set_style_outline_width(obj, 6, LV_STATE_DEFAULT); //边框宽度
lv_obj_set_style_outline_opa(obj, LV_OPA_20, LV_STATE_DEFAULT); //边框透明度, 0-255, 宏是百分比

image-20240528131921807

渐变

c
static lv_style_t style;

lv_style_init( &style );
lv_style_set_radius( &style, 20 );
lv_style_set_bg_opa( &style, LV_OPA_COVER ); //设置背景透明度
lv_style_set_bg_color( &style, lv_color_hex(0xff0000) ); //设置背景色
lv_style_set_bg_grad_color( &style, lv_color_hex( 0x0000ff ) ); //设置过度
lv_style_set_bg_grad_dir( &style, LV_GRAD_DIR_HOR ); //设置方向

lv_obj_t* btn = lv_btn_create( lv_scr_act() );
lv_obj_set_size( btn, 320, 120 );
lv_obj_center( btn );
lv_obj_add_style( btn, &style, LV_PART_MAIN );

image-20240529122053095

某一个部分

c
enum {
    LV_PART_MAIN         = 0x000000,   /**< A background like rectangle 主体*/
    LV_PART_SCROLLBAR    = 0x010000,   /**< The scrollbar(s) 滚动条*/
    LV_PART_INDICATOR    = 0x020000,   /**< Indicator, e.g. for slider, bar, switch, or the tick box of the checkbox 指示器(当前值)*/
    LV_PART_KNOB         = 0x030000,   /**< Like handle to grab to adjust the value 手柄或者旋钮(调整参数)*/
    LV_PART_SELECTED     = 0x040000,   /**< Indicate the currently selected option or section 选项框, 指示当前的选项*/
    LV_PART_ITEMS        = 0x050000,   /**< Used if the widget has multiple similar elements (e.g. table cells) 相似的元素, 单元格*/
    LV_PART_TICKS        = 0x060000,   /**< Ticks on scale e.g. for a chart or meter 可读*/
    LV_PART_CURSOR       = 0x070000,   /**< Mark a specific place e.g. for text area's cursor or on a chart 光标*/

    LV_PART_CUSTOM_FIRST = 0x080000,    /**< Extension point for custom widgets*/

    LV_PART_ANY          = 0x0F0000,    /**< Special value can be used in some functions to target all parts*/
};

image-20240528231342976

可以在手册里面查找某一个部件的组成部分

image-20240528231931398

image-20240528233308027

image-20240528233251301

这一个在设置的时候不能使用按位或的方式

c
lv_obj_t *slider = lv_slider_create(lv_scr_act());
lv_obj_set_align(slider, LV_ALIGN_CENTER);
lv_obj_set_style_bg_color(slider, lv_color_hex(0x00ff00), LV_STATE_DEFAULT | LV_PART_INDICATOR);

事件

lvgl里面发生用户感兴趣的事件的时候, 可以触发回调函数, 执行相关的函数

添加以及删除

c
struct _lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,void * user_data);
bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb);

event_cb: 回调函数

filter: 事件的类型

user_data: 用户的数据

c
typedef void (*lv_event_cb_t)(lv_event_t * e);
typedef struct _lv_event_t {
    struct _lv_obj_t * target;
    struct _lv_obj_t * current_target;
    lv_event_code_t code;
    void * user_data;
    void * param;
    struct _lv_event_t * prev;
    uint8_t deleted : 1;
    uint8_t stop_processing : 1;
    uint8_t stop_bubbling : 1;
} lv_event_t;

Events — LVGL documentation

事件类型

  • Input device events 输入事件
  • Drawing events 绘制事件
  • Other events 其他事件
  • Special events 特殊事件
  • Custom events 用户自定义事件
c
typedef enum {
    LV_EVENT_ALL = 0,

    /** Input device events*/
    LV_EVENT_PRESSED,             /**< The object has been pressed 按键按下*/
    LV_EVENT_PRESSING,            /**< The object is being pressed (called continuously while pressing) 按键按压的时候, 一直触发*/
    LV_EVENT_PRESS_LOST,          /**< The object is still being pressed but slid cursor/finger off of the object 按下但是光标移动*/
    LV_EVENT_SHORT_CLICKED,       /**< The object was pressed for a short period of time, then released it. Not called if scrolled. 短按, 滚动不触发*/
    LV_EVENT_LONG_PRESSED,        /**< Object has been pressed for at least `long_press_time`.  Not called if scrolled. 长按, 滚动不触发, 只触发一次*/
    LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `long_press_time` in every `long_press_repeat_time` ms.  Not called if scrolled. */
    LV_EVENT_CLICKED,             /**< Called on release if not scrolled (regardless to long press)*/
    LV_EVENT_RELEASED,            /**< Called in every cases when the object has been released 被释放*/
    LV_EVENT_SCROLL_BEGIN,        /**< Scrolling begins 滚动*/
    LV_EVENT_SCROLL_END,          /**< Scrolling ends*/
    LV_EVENT_SCROLL,              /**< Scrolling*/
    LV_EVENT_GESTURE,             /**< A gesture is detected. Get the gesture with `lv_indev_get_gesture_dir(lv_indev_get_act());` */
    LV_EVENT_KEY,                 /**< A key is sent to the object. Get the key with `lv_indev_get_key(lv_indev_get_act());`*/
    LV_EVENT_FOCUSED,             /**< The object is focused*/
    LV_EVENT_DEFOCUSED,           /**< The object is defocused*/
    LV_EVENT_LEAVE,               /**< The object is defocused but still selected*/
    LV_EVENT_HIT_TEST,            /**< Perform advanced hit-testing*/

    /** Drawing events*/
    LV_EVENT_COVER_CHECK,        /**< Check if the object fully covers an area. The event parameter is `lv_cover_check_info_t *`.*/
    LV_EVENT_REFR_EXT_DRAW_SIZE, /**< Get the required extra draw area around the object (e.g. for shadow). The event parameter is `lv_coord_t *` to store the size.*/
    LV_EVENT_DRAW_MAIN_BEGIN,    /**< Starting the main drawing phase*/
    LV_EVENT_DRAW_MAIN,          /**< Perform the main drawing*/
    LV_EVENT_DRAW_MAIN_END,      /**< Finishing the main drawing phase*/
    LV_EVENT_DRAW_POST_BEGIN,    /**< Starting the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_POST,          /**< Perform the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_POST_END,      /**< Finishing the post draw phase (when all children are drawn)*/
    LV_EVENT_DRAW_PART_BEGIN,    /**< Starting to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. */
    LV_EVENT_DRAW_PART_END,      /**< Finishing to draw a part. The event parameter is `lv_obj_draw_dsc_t *`. */

    /** Special events*/
    LV_EVENT_VALUE_CHANGED,       /**< The object's value has changed (i.e. slider moved)*/
    LV_EVENT_INSERT,              /**< A text is inserted to the object. The event data is `char *` being inserted.*/
    LV_EVENT_REFRESH,             /**< Notify the object to refresh something on it (for the user)*/
    LV_EVENT_READY,               /**< A process has finished*/
    LV_EVENT_CANCEL,              /**< A process has been cancelled */

    /** Other events*/
    LV_EVENT_DELETE,              /**< Object is being deleted*/
    LV_EVENT_CHILD_CHANGED,       /**< Child was removed, added, or its size, position were changed */
    LV_EVENT_CHILD_CREATED,       /**< Child was created, always bubbles up to all parents*/
    LV_EVENT_CHILD_DELETED,       /**< Child was deleted, always bubbles up to all parents*/
    LV_EVENT_SCREEN_UNLOAD_START, /**< A screen unload started, fired immediately when scr_load is called*/
    LV_EVENT_SCREEN_LOAD_START,   /**< A screen load started, fired when the screen change delay is expired*/
    LV_EVENT_SCREEN_LOADED,       /**< A screen was loaded*/
    LV_EVENT_SCREEN_UNLOADED,     /**< A screen was unloaded*/
    LV_EVENT_SIZE_CHANGED,        /**< Object coordinates/size have changed*/
    LV_EVENT_STYLE_CHANGED,       /**< Object's style has changed*/
    LV_EVENT_LAYOUT_CHANGED,      /**< The children position has changed due to a layout recalculation*/
    LV_EVENT_GET_SELF_SIZE,       /**< Get the internal size of a widget*/

    _LV_EVENT_LAST,               /** Number of default events*/


    LV_EVENT_PREPROCESS = 0x80,   /** This is a flag that can be set with an event so it's processed
                                      before the class default event processing */
} lv_event_code_t;

添加事件

c
static void event_cb(lv_event_t * obj){
    
    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello world!");
}

void my_gui(void){
    lv_obj_t * obj1 = lv_obj_create(lv_scr_act());
    lv_obj_add_event_cb(obj1, event_cb, LV_EVENT_CLICKED, NULL);
}
c
lv_event_code_t code = lv_event_get_code(obj);//获取这一个事件的类型
if(code == LV_EVENT_CLICKED){
    lv_obj_t * label = lv_label_create(lv_scr_act());
    lv_label_set_text(label, "Hello world!");
}

image-20240529221328542

滚动属性

子对象超出父对象的范围区域,则该父对象会自动开启滚动条

设置模式

c
void lv_obj_set_scrollbar_mode(lv_obj_t * obj, lv_scrollbar_mode_t mode);
c
/** Scrollbar modes: shows when should the scrollbars be visible*/
enum {
    LV_SCROLLBAR_MODE_OFF,      /**< Never show scrollbars*/
    LV_SCROLLBAR_MODE_ON,       /**< Always show scrollbars*/
    LV_SCROLLBAR_MODE_ACTIVE,   /**< Show scroll bars when object is being scrolled*/
    LV_SCROLLBAR_MODE_AUTO,     /**< Show scroll bars when the content is large enough to be scrolled*/
};
typedef uint8_t lv_scrollbar_mode_t;

可以触发的事件

c
LV_EVENT_SCROLL_BEGIN,        /**< Scrolling begins 滚动*/
LV_EVENT_SCROLL_END,          /**< Scrolling ends*/
LV_EVENT_SCROLL,              /**< Scrolling*/

设置滚动方向

c
void lv_obj_set_scroll_dir(lv_obj_t * obj, lv_dir_t dir);
c
enum {
    LV_DIR_NONE     = 0x00,
    LV_DIR_LEFT     = (1 << 0),
    LV_DIR_RIGHT    = (1 << 1),
    LV_DIR_TOP      = (1 << 2),
    LV_DIR_BOTTOM   = (1 << 3),
    LV_DIR_HOR      = LV_DIR_LEFT | LV_DIR_RIGHT,
    LV_DIR_VER      = LV_DIR_TOP | LV_DIR_BOTTOM,
    LV_DIR_ALL      = LV_DIR_HOR | LV_DIR_VER,
};

其他属性

可以通过lv_obj_add/clear_flag进行设置

滚动传递

子对象到达父对象的边缘的时候, 是不是会把滚动的属性传递的父对象, LV_OBJ_FLAG_SCROLL_CHAIN_HOR/VER进行启用

滚动惯性

LV_OBJ_FLAG_SCROLL_MOMENTUM这一个属性进行启用

弹性滚动

超出以后会有一个回弹

动画

LVGL库入门教程 - 动画 - 冰封残烛 - 博客园 (cnblogs.com)

过渡动画

在一个对象的属性发生变化的时候的动画, 需要使用lv_style_transition_dsc_t这一个属性进行设置

c
typedef struct {
    const lv_style_prop_t * props; /**< An array with the properties to animate. 需要过度的属性*/
#if LV_USE_USER_DATA
    void * user_data;              /**< A custom user data that will be passed to the animation's user_data */
#endif
    lv_anim_path_cb_t path_xcb;     /**< A path for the animation. 过渡动画*/
    uint32_t time;                 /**< Duration of the transition in [ms] 过度的时间*/
    uint32_t delay;                /**< Delay before the transition in [ms] 过度的延迟*/
} lv_style_transition_dsc_t;
c
void lv_style_transition_dsc_init(
                lv_style_transition_dsc_t* tr, 
                const lv_style_prop_t props[],
                lv_anim_path_cb_t path_cb, 
                uint32_t time, 
                uint32_t delay, 
                void* user_data);

第一个参数需要提供被初始化的过渡动画结构,第二个参数数组和字符串一样需要以 0 结尾。

c
lv_obj_t * obj1 = lv_obj_create(lv_scr_act());
lv_obj_add_event_cb(obj1, event_cb, LV_EVENT_CLICKED, NULL);

static lv_style_transition_dsc_t trans;
static const lv_style_prop_t trans_props[] = {
    LV_STYLE_WIDTH, LV_STYLE_HEIGHT, LV_STYLE_BG_COLOR, 0,
};
lv_style_transition_dsc_init(&trans, trans_props, lv_anim_path_ease_in_out, 500, 0, NULL);

static lv_style_t style_trans;
lv_style_init(&style_trans);
lv_style_set_transition(&style_trans, &trans);

lv_style_set_bg_color(&style_trans, lv_palette_main(LV_PALETTE_RED));
lv_style_set_width(&style_trans, 150);
lv_style_set_height(&style_trans, 60);
lv_obj_add_style(obj1, &style_trans, LV_STATE_PRESSED);

image-20240529225228906

image-20240529224918264

通用动画

①定义一个 lv_anim_t 变量。

② 调用函数 lv_anim_init 初始化动画。

③ 调用函数 lv_anim_set_exec_cb 设置动画回调函数。

④ 调用函数 lv_anim_set_var 设置动画执行的目标。

⑤ 调用函数 lv_anim_set_time 设置动画时间长度。

⑥ 调用函数 lv_anim_set_values 设置起始值和结束值。

⑦ 调用函数 lv_anim_start 开始动画。

c
lv_obj_t * obj1 = lv_obj_create(lv_scr_act());
lv_anim_t anim;
lv_anim_init(&anim);
lv_anim_set_var(&anim, obj1); //设置对象
lv_anim_set_exec_cb(&anim, (lv_anim_exec_xcb_t)lv_obj_set_y); //设置回调函数
lv_anim_set_values(&anim, -100, 100); //设置起始位置, 结束位置
lv_anim_set_path_cb(&anim, lv_anim_path_bounce);
lv_anim_set_time(&anim, 1000);
lv_anim_set_delay(&anim, 1000);
lv_anim_start(&anim);
c
static void anim_progress_load(void *obj, int32_t v)
{
    lv_bar_set_start_value(obj, v, LV_ANIM_ON);
    lv_bar_set_value(obj, 20 + v, LV_ANIM_ON);
}

lv_obj_t *bar = lv_bar_create(lv_scr_act());
lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);
static lv_style_t style_bg;
static lv_style_t style_indic;
//设置样式
lv_style_init(&style_bg);
lv_style_set_border_color(&style_bg, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_border_width(&style_bg, 2);
lv_style_set_pad_all(&style_bg, 6);
lv_style_set_radius(&style_bg, 6);
lv_style_set_anim_time(&style_bg, 1000);
lv_style_init(&style_indic);
lv_style_set_bg_opa(&style_indic, LV_OPA_COVER);
lv_style_set_bg_color(&style_indic, lv_palette_main(LV_PALETTE_BLUE));
lv_style_set_radius(&style_indic, 3);
lv_obj_remove_style_all(bar);
lv_obj_add_style(bar, &style_bg, 0);
lv_obj_add_style(bar, &style_indic, LV_PART_INDICATOR);
lv_obj_set_size(bar, 200, 20);
lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0);
//设置动画
lv_anim_t anim;
lv_anim_init(&anim);
lv_anim_set_var(&anim, bar);
lv_anim_set_exec_cb(&anim, anim_progress_load); //设置回调函数
lv_anim_set_values(&anim, 0, 80);
lv_anim_set_path_cb(&anim, lv_anim_path_linear);
lv_anim_set_time(&anim, 1500);
lv_anim_set_delay(&anim, 0);
lv_anim_set_playback_time(&anim, 1500);
lv_anim_set_repeat_count(&anim, LV_ANIM_REPEAT_INFINITE);

时间线

c
lv_anim_timeline_t* anim_timeline = lv_anim_timeline_create();
lv_anim_timeline_add(anim_timeline, 0, &anim_axis);
lv_anim_timeline_add(anim_timeline, 100, &anim_obj_01);
lv_anim_timeline_add(anim_timeline, 1100, &anim_obj_02);
lv_anim_timeline_add(anim_timeline, 2100, &anim_obj_03);
lv_anim_timeline_add(anim_timeline, 300, &anim_label_01);
lv_anim_timeline_add(anim_timeline, 1300, &anim_label_02);
lv_anim_timeline_add(anim_timeline, 2300, &anim_label_03);

lv_anim_timeline_start(anim_timeline);启动这一个时间线