闭门造轮(LVGL_2)

例程1_// 组件(widgets): 标签(label)的用法

static void label_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);        // 获取触发事件的部件(对象)
    lv_event_code_t code = lv_event_get_code(e);    // 获取当前部件(对象)触发的事件代码

    switch(code){
        case LV_EVENT_PRESSED:
            //lv_label_set_text(label, "LV_EVENT_PRESSED");
            //lv_obj_set_style_bg_color(obj, lv_color_hex(0xc43e1c), 0);  // 通过本地样式(私有样式)设置背景色
            printf("LV_EVENT_PRESSED\n");
            break;
        case LV_EVENT_LONG_PRESSED:
            //lv_label_set_text(label, "LV_EVENT_LONG_PRESSED");
            //lv_obj_set_style_bg_color(obj, lv_color_hex(0x4cbe37), 0);  // 通过本地样式(私有样式)设置背景色
            printf("LV_EVENT_LONG_PRESSED\n");
            break;
        default:
            //printf("NONE\n");
            break;
    }
}

void lv_100ask_demo_course_3_1_1(void)
{
    char * text = "hello lvgl";   // 要显示的文字

    /* 创建一个基础对象 label */
    lv_obj_t * label = lv_label_create(lv_scr_act());   // 创建一个label部件(对象),他的父对象是活动屏幕对象


    /* 展示文字 */
    /* 设置要显示的文本,函数中会另外开辟和给定的字符串大小的空间存放字符串(常用) */
    lv_label_set_text(label, text);
    //lv_label_set_text(label, "www.100ask.net"); // 也可以这样使用

    /* 设置要显示的文字,也会另外开辟空间存放字符串,但是可以像 printf 格式化字符串 */
    //lv_label_set_text_fmt(label, "%s: %d", "Value", 15);

    /* 设置要显示的文字,直接使用给定的缓冲区(不常用) */
    //lv_label_set_text_static(label, text);
    //lv_label_set_text_static(label, "www.100ask.net"); // 也可以这样使用


    /* 设置文字字号(内置ASCII字库) */
    /* 使用其他字号的字体,如果不设置默认使用 lv_font_montserrat_14 ,在 lv_conf.h 中 LV_FONT_DEFAULT 定义 */
    lv_obj_set_style_text_font(label, &lv_font_montserrat_28, 0);  // 为了方便,这里使用本地(私有)样式


    /* 让 label 可以响应输入事件 */
    lv_obj_add_flag(label, LV_OBJ_FLAG_CLICKABLE);
    lv_obj_add_event_cb(label, label_event_cb, LV_EVENT_ALL, 0);
}

这段代码主要是介绍了,各种添加文字的方法,甚至有通过点击文字来进入回调事件的方法。,比较简单就不介绍了。

例程2_// 组件(widgets): 按钮(lv_btn)的用法

static void btn_toggle_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);        // 获取触发事件的部件(对象)
    lv_event_code_t code = lv_event_get_code(e);    // 获取当前部件(对象)触发的事件代码

    switch(code){
        case LV_EVENT_VALUE_CHANGED:
            printf("LV_EVENT_VALUE_CHANGED\n");
            break;
        default:
            //printf("NONE\n");
            break;
    }
}

void lv_100ask_demo_course_3_2_1(void)
{
    /* 创建一个btn部件(对象) */
    lv_obj_t * btn = lv_btn_create(lv_scr_act());       // 创建一个btn部件(对象),他的父对象是活动屏幕对象

    // 修改按钮部件(对象)矩形背景部分的样式
    lv_obj_set_style_bg_color(btn, lv_color_hex(0x1e1e1e), LV_PART_MAIN | LV_STATE_PRESSED);

    // 打开了 LV_OBJ_FLAG_CHECKABLE ,当对象被点击时有选中切换(Toggle)状态的效果
    // 其触发的是 LV_EVENT_VALUE_CHANGED 事件类型
    lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);

    // 处理 LV_EVENT_VALUE_CHANGED 事件类型示例
    lv_obj_add_event_cb(btn, btn_toggle_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
}
  1. lv_obj_t * btn = lv_btn_create(lv_scr_act()):创建一个按钮对象,并将其父对象设置为活动屏幕对象。

  2. lv_obj_set_style_bg_color(btn, lv_color_hex(0x1e1e1e), LV_PART_MAIN | LV_STATE_PRESSED):将按钮对象的背景色设置为灰色,并在按钮被按下时设置为按下状态。

  3. lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE):为按钮对象添加 LV_OBJ_FLAG_CHECKABLE 标志,使其具有可选中状态。

  4. lv_obj_add_event_cb(btn, btn_toggle_event_cb, LV_EVENT_VALUE_CHANGED, NULL):为按钮对象添加 LV_EVENT_VALUE_CHANGED 事件回调函数,即 btn_toggle_event_cb。当按钮对象的值发生变化时,该回调函数将被触发。

  5. 在 btn_toggle_event_cb 回调函数中,通过 lv_event_get_target(e) 获取触发事件的对象,通过 lv_event_get_code(e) 获取当前对象触发的事件代码。在这个例子中,只处理 LV_EVENT_VALUE_CHANGED 事件类型,在回调函数中打印出该事件类型的名称。

例程3_// 组件(widgets): 使用物理按键代替触摸(groups)

// 用Windows PC模拟器键盘或鼠标需要包含此头文件
#include "lv_drivers/win32drv/win32drv.h"

void lv_100ask_demo_course_3_3_1(void)
{
    // 创建一个组,稍后将需要使用键盘或编码器或按钮控制的部件(对象)添加进去,并且将输入设备和组关联
    // 如果将这个组设置为默认组,那么对于那些在创建时会添加到默认组的部件(对象)就可以省略 lv_group_add_obj()
    lv_group_t * g = lv_group_create();

    // 将上面创建的组设置为默认组
    // 如果稍后创建的部件(对象),使用默认组那必须要在其创建之前设置好默认组,否则不生效
    lv_group_set_default(g);

    // 将输入设备和组关联(使用前先打开上面注释掉的头文件)
    lv_indev_set_group(lv_win32_keypad_device_object, g);     // 键盘
    lv_indev_set_group(lv_win32_encoder_device_object, g);      // 鼠标上的滚轮(编码器)


    /* 创建一个btn部件(对象) */
    lv_obj_t * btn1 = lv_btn_create(lv_scr_act());       // 创建一个btn部件(对象),他的父对象是活动屏幕对象
    lv_obj_set_size(btn1, 100, 50);
    lv_obj_align(btn1, LV_ALIGN_CENTER, 0, -100);

    lv_obj_t * btn2 = lv_btn_create(lv_scr_act());       // 创建一个btn部件(对象),他的父对象是活动屏幕对象
    lv_obj_set_size(btn2, 100, 50);
    lv_obj_align_to(btn2, btn1, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    lv_obj_t * btn3 = lv_btn_create(lv_scr_act());       // 创建一个btn部件(对象),他的父对象是活动屏幕对象
    lv_obj_set_size(btn3, 100, 50);
    lv_obj_align_to(btn3, btn2, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    lv_obj_t * btn4 = lv_btn_create(lv_scr_act());       // 创建一个btn部件(对象),他的父对象是活动屏幕对象
    lv_obj_set_size(btn4, 100, 50);
    lv_obj_align_to(btn4, btn3, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    lv_obj_t * slider = lv_slider_create(lv_scr_act());
    lv_obj_align_to(slider, btn4, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    // 将部件(对象)添加到组,如果设置了默认组,这里可以省略
    //lv_group_add_obj(g, btn1);
    //lv_group_add_obj(g, btn2);
    //lv_group_add_obj(g, btn3);
    //lv_group_add_obj(g, btn4);
    //lv_group_add_obj(g, slider);

}

 这份代码,主要是从只能由触摸屏手指点击来操作滑杆,按键等样式的基础上,增加了使用键盘和鼠标滚轮等方式来控制

闭门造轮(LVGL_2)_第1张图片

 按下键盘的ENTER可以按下按键,通过键盘的上下左右也可以控制滑杆的移动,鼠标滚轮则是可以上下滑动来选择你要控制的对象样式

例程4_// 组件(widgets): 开关(lv_switch)的用法

static void sw_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *sw = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        // 判断开关状态
        /* 方式1 */
        // 返回 bool 类型, 开-1 ; 关-2
        //if(lv_obj_has_state(sw, LV_STATE_CHECKED))
        //    LV_LOG_USER("ON!");
        //else
        //    LV_LOG_USER("OFF!");

        // 更简介的写法
        //LV_LOG_USER("State: %s", lv_obj_has_state(sw, LV_STATE_CHECKED) ? "ON" : "OFF");


        /* 方式2 */
        if(lv_obj_get_state(sw) & LV_STATE_CHECKED)
            LV_LOG_USER("ON!");
        else
            LV_LOG_USER("OFF!");
        LV_LOG_USER("State: %s", (lv_obj_get_state(sw) & LV_STATE_CHECKED) ? "ON" : "OFF");
    }

}


void lv_100ask_demo_course_3_4_1(void)
{
    /* 创建一个 switch 部件(对象) */
    lv_obj_t * sw = lv_switch_create(lv_scr_act());         // 创建一个 switch 部件(对象),他的父对象是活动屏幕对象
    //lv_obj_center(sw);                                    // 方法1:让对象居中,简洁
    lv_obj_align(sw, LV_ALIGN_CENTER, 0, 0);                // 方法2:让对象居中,较为灵活

    // 修改开关对象的大小,注意比例不能是 1:1 (比如:宽高都是100),否则只能看到一个大圆
    //lv_obj_set_size(sw, 200, 100);

    // 开操作
    //lv_obj_add_state(sw, LV_STATE_CHECKED);                       // 开关默认处于关闭状态,这里设置为打开状态
    //lv_obj_add_state(sw, LV_STATE_CHECKED | LV_STATE_DISABLED);   // 当前状态是开,并且不可更改

    // 关操作
    //lv_obj_clear_state(sw, LV_STATE_CHECKED);	                    // 关
    //lv_obj_add_state(sw, LV_STATE_DISABLED); 		                // 当前状态是关,并且不可更改

    // 清除禁用状态,一般由其他部件(外部)清除
    //lv_obj_clear_state(sw, LV_STATE_ DISABLED);                   // 清除禁用状态,按钮可正常使用

    // 添加事件,当我们点击开关,改变开关的状态时,会触发 LV_EVENT_VALUE_CHANGED 事件类型
    // 当然我们可以处理他触发的其他事件类型,比如: LV_EVENT_CLICKED
    lv_obj_add_event_cb(sw, sw_event_handler, LV_EVENT_VALUE_CHANGED, NULL);

}

闭门造轮(LVGL_2)_第2张图片

 代码比较简单,API在之前也讲过,就不赘述了,主要现象也很简单

例程5_// 组件(widgets): 复选框(lv_checkbox)的用法

static void cb_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *cb = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        const char * txt = lv_checkbox_get_text(cb);

        // 判断开关状态
        /* 方式1 */
        // 返回 bool 类型, 开-1 ; 关-2
        //if(lv_obj_has_state(cb, LV_STATE_CHECKED))
        //    LV_LOG_USER("%s: CHECKED!", txt);
        //else
        //    LV_LOG_USER("%s: UNCHECKED!", txt);

        // 更简介的写法
        //LV_LOG_USER("%s: %s", txt, lv_obj_has_state(cb, LV_STATE_CHECKED) ? "CHECKED" : "UNCHECKED");


        /* 方式2 */
        if(lv_obj_get_state(cb) & LV_STATE_CHECKED)
            LV_LOG_USER("%s: CHECKED!", txt);
        else
            LV_LOG_USER("%s: UNCHECKED!", txt);
        LV_LOG_USER("%s: %s", txt, (lv_obj_get_state(cb) & LV_STATE_CHECKED) ? "CHECKED" : "UNCHECKED");
    }

}

void lv_100ask_demo_course_3_5_1(void)
{
    /* 创建一个 checkbox 部件(对象) */
    lv_obj_t * cb = lv_checkbox_create(lv_scr_act());     // 创建一个 switch 部件(对象),他的父对象是活动屏幕对象
    lv_checkbox_set_text(cb, "do you like it ?" LV_SYMBOL_PLAY);  // 修改复选框的提示文字(覆盖)

    //lv_obj_center(cb);                                    // 方法1:让对象居中,简洁
    lv_obj_align(cb, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

    lv_obj_set_style_text_font(cb, &lv_font_montserrat_32, 0); // 修改复选框提示文字的字体
    //lv_obj_set_style_pad_all(cb, 20, LV_PART_INDICATOR);       // 修改复选框勾选框的大小
    //lv_obj_set_style_pad_column(cb, 100, 0);                   // 设置复选框的勾选框和提示文字的距离

    //lv_obj_set_style_bg_opa(cb, 100, LV_PART_MAIN);                         // 修改复选框的背景透明度
    //lv_obj_set_style_bg_color(cb, lv_color_hex(0xc43e1c), LV_PART_MAIN);    // 修改复选框的背景颜色

    //lv_obj_set_style_bg_color(cb, lv_color_hex(0xc43e1c), LV_PART_INDICATOR);   // 修改勾选框部分,勾选时的背景颜色
    //lv_obj_set_style_bg_color(cb, lv_color_hex(0x7719aa), LV_PART_INDICATOR | LV_STATE_CHECKED); // 修改勾选框部分,不勾选时的背景颜色


    // 勾选操作
    //lv_obj_add_state(cb, LV_STATE_CHECKED);                       // 复选框默认处于不勾选状态,这里设置为勾选状态状态
    //lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);   // 当前状态是勾选状态,并且不可更改

    // 不勾选操作
    //lv_obj_clear_state(cb, LV_STATE_CHECKED);	        // 不勾选
    //lv_obj_add_state(cb, LV_STATE_DISABLED); 		    // 当前状态是不勾选状态,并且不可更改

    // 清除禁用状态,一般由其他部件(外部)清除
    //lv_obj_clear_state(cb, LV_STATE_DISABLED);       // 清除禁用状态,复选框可正常使用

    // 添加事件,当我们点击复选框,改变勾选框的状态时,会触发 LV_EVENT_VALUE_CHANGED 事件类型
    // 当然我们可以处理他触发的其他事件类型,比如: LV_EVENT_CLICKED
    lv_obj_add_event_cb(cb, cb_event_handler, LV_EVENT_VALUE_CHANGED, NULL);
}

相关API:

lv_obj_t * cb = lv_checkbox_create(lv_scr_act());     // 创建一个 switch 部件(对象),他的父对象是活动屏幕对象
lv_checkbox_set_text(cb, "do you like it ?" LV_SYMBOL_PLAY);  // 修改复选框的提示文字(覆盖)

lv_obj_align(cb, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

 只运行这三句代码的现象如下:闭门造轮(LVGL_2)_第3张图片

 lv_obj_set_style_text_font(cb, &lv_font_montserrat_32, 0); // 修改复选框提示文字的字体

 增加以下代码后,主要更改的是提示字体的大小,可选参数有:

#define LV_FONT_MONTSERRAT_8  1
#define LV_FONT_MONTSERRAT_10 1
#define LV_FONT_MONTSERRAT_12 1
#define LV_FONT_MONTSERRAT_14 1
#define LV_FONT_MONTSERRAT_16 1
#define LV_FONT_MONTSERRAT_18 1
#define LV_FONT_MONTSERRAT_20 1
#define LV_FONT_MONTSERRAT_22 1
#define LV_FONT_MONTSERRAT_24 1
#define LV_FONT_MONTSERRAT_26 1
#define LV_FONT_MONTSERRAT_28 1
#define LV_FONT_MONTSERRAT_30 1
#define LV_FONT_MONTSERRAT_32 1
#define LV_FONT_MONTSERRAT_34 1
#define LV_FONT_MONTSERRAT_36 1
#define LV_FONT_MONTSERRAT_38 1
#define LV_FONT_MONTSERRAT_40 1
#define LV_FONT_MONTSERRAT_42 1
#define LV_FONT_MONTSERRAT_44 1
#define LV_FONT_MONTSERRAT_46 1
#define LV_FONT_MONTSERRAT_48 1

闭门造轮(LVGL_2)_第4张图片

 lv_obj_set_style_pad_all(cb, 20, LV_PART_INDICATOR);       // 修改复选框勾选框的大小

闭门造轮(LVGL_2)_第5张图片

 lv_obj_set_style_pad_column(cb, 100, 0);                   // 设置复选框的勾选框和提示文字的距离

闭门造轮(LVGL_2)_第6张图片

 lv_obj_set_style_bg_opa(cb, 100, LV_PART_MAIN);                         // 修改复选框的背景透明度

闭门造轮(LVGL_2)_第7张图片

 lv_obj_set_style_bg_color(cb, lv_color_hex(0xc43e1c), LV_PART_MAIN);    // 修改复选框的背景颜色

闭门造轮(LVGL_2)_第8张图片

lv_obj_set_style_bg_color(cb, lv_color_hex(0xc43e1c), LV_PART_INDICATOR);   // 修改勾选框部分,勾选时的背景颜色
lv_obj_set_style_bg_color(cb, lv_color_hex(0x7719aa), LV_PART_INDICATOR | LV_STATE_CHECKED); // 修改勾选框部分,不勾选时的背景颜色

闭门造轮(LVGL_2)_第9张图片

闭门造轮(LVGL_2)_第10张图片

设置勾选框的初始状态:

// 勾选操作
//lv_obj_add_state(cb, LV_STATE_CHECKED);                       // 复选框默认处于不勾选状态,这里设置为勾选状态状态
//lv_obj_add_state(cb, LV_STATE_CHECKED | LV_STATE_DISABLED);   // 当前状态是勾选状态,并且不可更改

// 不勾选操作
//lv_obj_clear_state(cb, LV_STATE_CHECKED);                        // 不勾选
//lv_obj_add_state(cb, LV_STATE_DISABLED);                         // 当前状态是不勾选状态,

并且不可更改

// 清除禁用状态,一般由其他部件(外部)清除
//lv_obj_clear_state(cb, LV_STATE_DISABLED);       // 清除禁用状态,复选框可正常使用

例程6_// 组件(widgets): 下拉列表(lv_dropdown))的用法

static void btn_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);
    lv_obj_t *dd  = lv_event_get_user_data(e);

    if(code == LV_EVENT_VALUE_CHANGED) {
        // 由于 btn 在初始化时已经设置了 LV_OBJ_FLAG_CHECKABLE
        // 那么这里就可以检查 btn 当前的状态,达到打开或关闭下拉列表的目的
        // 这里的用法请参考 3_5_1 和 3_4_1
        if(lv_obj_has_state(btn, LV_STATE_CHECKED))
            lv_dropdown_open(dd);
        else
            lv_dropdown_close(dd);
    }

}

static void dd_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *obj = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        LV_LOG_USER("%d", lv_dropdown_get_selected(obj));       // 获取选项的索引值,从0开始
        char tmp_buf[32];
        lv_dropdown_get_selected_str(obj, tmp_buf, sizeof(tmp_buf)); // 获取选项的内容
        LV_LOG_USER("%s", tmp_buf);
    }
    else if(code == LV_EVENT_CLICKED)
    {
        // 改变下拉列表中列表的样式
        // 这些修改可以在初始化的时候就设置好,你也可以像下面这样动态地修改样式
        lv_obj_t * dd_list = lv_dropdown_get_list(obj);
        if(dd_list != NULL)
        {
            // 需要在 lv_conf.h 中打开宏 LV_FONT_MONTSERRAT_28,要使用其他内置字体同理
            // 注意:如果你初始化时使用了中文字库,并且设置了中文选项,这里设置之后内容将不能展示出来
            //lv_obj_set_style_text_font(dd_list, &lv_font_montserrat_28, 0);

            // 修改列表的背景颜色
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xc43e1c), 0);
            //lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xc43e1c), LV_PART_MAIN); // 这样写和上面那个是一样的

            // 修改滚动条的样式
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_border_color(dd_list, lv_color_hex(0xcc3e1c), LV_PART_SCROLLBAR);

            // 修改当按下、选中或按下+选中选项时的样式
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xafbeac), LV_PART_SELECTED);

        }
    }
}

void lv_100ask_demo_course_3_6_1(void)
{

#if 0
    // 使用物理按键控制,注意上面要包含 "lv_drivers/win32drv/win32drv.h",
    // LVGL按键控制,视频教程: https://www.bilibili.com/video/BV1Ya411r7K2?p=19
    // 创建一个组,稍后将需要使用键盘或编码器或按钮控制的部件(对象)添加进去,并且将输入设备和组关联
    // 如果将这个组设置为默认组,那么对于那些在创建时会添加到默认组的部件(对象)就可以省略 lv_group_add_obj()
    lv_group_t * g = lv_group_create();

    // 将上面创建的组设置为默认组
    // 如果稍后创建的部件(对象),使用默认组那必须要在其创建之前设置好默认组,否则不生效
    lv_group_set_default(g);

    // 将输入设备和组关联(使用前先打开上面注释掉的头文件)
    lv_indev_set_group(lv_win32_keypad_device_object, g);     // 键盘
    lv_indev_set_group(lv_win32_encoder_device_object, g);      // 鼠标上的滚轮(编码器)

#endif // 0

    /* 创建一个 lv_dropdown 部件(对象) */
    lv_obj_t * dd = lv_dropdown_create(lv_scr_act());    // 创建一个 lv_dropdown 部件(对象),他的父对象是活动屏幕对象

    // 将部件(对象)添加到组,如果设置了默认组,这里可以省略,因为 lv_dropdown 是 LV_OBJ_CLASS_GROUP_DEF_TRUE
    //lv_group_add_obj(g, dd);

#if 1
    lv_dropdown_set_options(dd, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10");  // 写法1:添加选项,索引从0开始
#if 0
    lv_dropdown_set_options(dd, "1\n"
                                "2\n"
                                "3\n"
                                "4\n"
                                "5\n"
                                "6\n"
                                "7\n"
                                "8\n"
                                "9\n"
                                "10"); // 写法2:添加选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)
#endif // 写法1:添加选项,索引从0开始
#endif // 写法2:添加选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)

    lv_obj_center(dd);                                    // 方法1:让对象居中,简洁
    //lv_obj_align(dd, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

#if 0
    // 获取下拉列表中的列表来修改样式或其他修改
    lv_obj_t * dd_list = lv_dropdown_get_list(dd);

#if 0
    // 显示中文
    // 修改列表所使用的字体,如果要展示中文则要在这里设置
    LV_FONT_DECLARE(lv_font_source_han_sans_bold_14);   // 声明字体,可以放到函数外部
    lv_obj_set_style_text_font(dd, &lv_font_source_han_sans_bold_14, 0);        // 设置新的字体(下拉列表的按钮)
    lv_obj_set_style_text_font(dd_list, &lv_font_source_han_sans_bold_14, 0);   // 设置新的字体(下拉列表中的列表)
    lv_dropdown_set_options(dd, "一\n二\n三\n四\n五\n六\n七\n八\n九\n十");      // 设置中文选项
    //lv_dropdown_set_symbol(dd, LV_SYMBOL_CALL);   // 注意:如果使用自定义的字库,并且你的字库中没有这些符号,那么下拉列表的符号就不会显示了
#endif

    // 使用内置字体
    lv_obj_set_style_text_font(dd, &lv_font_montserrat_30, 0);          // 设置新的字体(下拉列表的按钮)
    lv_obj_set_style_text_font(dd_list, &lv_font_montserrat_30, 0);     // 设置新的字体(下拉列表中的列表)

    // 设置字体对齐位置
    //lv_obj_set_style_text_align(dd, LV_TEXT_ALIGN_CENTER, 0);           // 这样设置下拉列表的按钮的文字对齐位置不会生效,可以在 LV_EVENT_DRAW_MAIN 事件中修改,但是不建议修改,详情请阅读 lv_dropdown.c 的源码
    lv_obj_set_style_text_align(dd_list, LV_TEXT_ALIGN_RIGHT, 0);       // 设置下拉列表中的列表的文字对齐
    
#endif // 0

    //lv_dropdown_add_option(dd, "11", 10);         // 追加一个选项
    //lv_dropdown_add_option(dd, "十一", 10);       // 追加一个选项(使用中文的时候)
    //lv_dropdown_set_selected(dd, 3);              // 设置默认选中的选项,索引从0开始
    //lv_dropdown_set_symbol(dd, LV_SYMBOL_CALL);   // 设置按钮显示的字符
    //lv_dropdown_set_text(dd, "Some text");        // 设置当选中选项之后展示的内容,如果没有这句,那么选中的是什么就展示什么

#if 0
    // 改变列表创建的方向
    // 下拉列表按钮上的符号会跟随 所设置的方向自动调整(左侧或右侧)
    // 官方参考示例:  http://lvgl.100ask.net/8.2/widgets/core/dropdown.html#drop-down-in-four-directions

    lv_dropdown_set_dir(dd, LV_DIR_LEFT);     // 左侧
    lv_dropdown_set_dir(dd, LV_DIR_RIGHT);    // 右侧
    lv_dropdown_set_dir(dd, LV_DIR_TOP);      // 顶部
    lv_dropdown_set_dir(dd, LV_DIR_BOTTOM);   // 底部
#endif // 0

    // 添加事件
    // 当我们点击下拉列表时,会触发 LV_EVENT_CLICKED 事件类型,并且会创建出一个列表,列表中展示我们在前面设置的选项供我们选择
    // 当我们选中一个选项时,会触发 LV_EVENT_VALUE_CHANGED 事件类型
    lv_obj_add_event_cb(dd, dd_event_handler, LV_EVENT_ALL, NULL);

#if 1
    // 通过其他部件打开或关闭下拉列表
    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);
    lv_obj_align_to(btn, dd, LV_ALIGN_OUT_TOP_MID, 0, -10);
    lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_VALUE_CHANGED , dd);
#endif // 1

}

 这个例程的代码有点多,我们一步步来

在lv_100ask_demo_course_3_6_1中:

#include "lv_drivers/win32drv/win32drv.h"

lv_group_t * g = lv_group_create();                         // 创建一个组
lv_group_set_default(g);                                    // 设置这个组为默认组(部件在创建后自动添加到组中)
lv_indev_set_group(lv_win32_keypad_device_object, g);       // 键盘
lv_indev_set_group(lv_win32_encoder_device_object, g);      // 鼠标上的滚轮(编码器)

这部分代码主要是将键盘和鼠标滚轮等物理设备和g(组)进行关联。

/* 创建一个 lv_dropdown 部件(对象) */
lv_obj_t * dd = lv_dropdown_create(lv_scr_act());    // 创建一个 lv_dropdown 部件(对象),他的父对象是活动屏幕对象
#if 1
    lv_dropdown_set_options(dd, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10");  // 写法1:添加选项,索引从0开始
#if 0
    lv_dropdown_set_options(dd, "1\n"
                                "2\n"
                                "3\n"
                                "4\n"
                                "5\n"
                                "6\n"
                                "7\n"
                                "8\n"
                                "9\n"
                                "10"); // 写法2:添加选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)
#endif // 写法1:添加选项,索引从0开始
#endif // 写法2:添加选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)

这两部分代码主要是创建了个下拉列表的部件,并且下拉列表的选项格式的两种写法也给出了。

lv_obj_align(dd, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

让下拉列表居中,其实代码中给了两种位置调整方法,我觉得还是有参数调整的这种API能够适应多种场景。

lv_obj_t * dd_list = lv_dropdown_get_list(dd);

获取下拉列表的列表部分进行操作。

lv_obj_set_style_text_font(dd, &lv_font_montserrat_30, 0);          // 设置新的字体(下拉列表的按钮)
lv_obj_set_style_text_font(dd_list, &lv_font_montserrat_30, 0);     // 设置新的字体(下拉列表中的列表)

修改下拉列表的按键和下拉列表列表部分的字体

lv_obj_set_style_text_align(dd, LV_TEXT_ALIGN_CENTER, 0);           // 这样设置下拉列表的按钮的文字对齐位置不会生效,可以在 LV_EVENT_DRAW_MAIN 事件中修改,但是不建议修改,详情请阅读 lv_dropdown.c 的源码
lv_obj_set_style_text_align(dd_list, LV_TEXT_ALIGN_CENTER, 0);       // 设置下拉列表中的列表的文字对齐

调整字体的位置

lv_dropdown_add_option(dd, "11", 10);         // 追加一个选项

添加一个"11"的选项

lv_dropdown_set_selected(dd, 5);              // 设置默认选中的选项,索引从0开始

设置初始选项为6(索引从0开始)

lv_dropdown_set_symbol(dd, LV_SYMBOL_CALL);   // 设置按钮显示的字符

显示按钮字符:

闭门造轮(LVGL_2)_第11张图片

lv_dropdown_set_text(dd, "Some text");        // 设置当选中选项之后展示的内容,如果没有这句,那么选中的是什么就展示什么

添加选项中的字体:

闭门造轮(LVGL_2)_第12张图片

lv_dropdown_set_dir(dd, LV_DIR_LEFT);     // 左侧
lv_dropdown_set_dir(dd, LV_DIR_RIGHT);    // 右侧
lv_dropdown_set_dir(dd, LV_DIR_TOP);      // 顶部
lv_dropdown_set_dir(dd, LV_DIR_BOTTOM);   // 底部

更改下拉列表的弹出的位置

// 通过其他部件打开或关闭下拉列表
lv_obj_t * btn = lv_btn_create(lv_scr_act());    //创建一个按钮部件
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE);        //设置该按钮部件能够被选中
lv_obj_align_to(btn, dd, LV_ALIGN_OUT_TOP_MID, 0, -10);    //设置按钮的位置
lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_VALUE_CHANGED , dd);    //该按钮对应btn_event_handler回调函数

增加一个按钮部件,添加回调函数等

static void btn_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);
    lv_obj_t *dd  = lv_event_get_user_data(e);

    if(code == LV_EVENT_VALUE_CHANGED) {
        // 由于 btn 在初始化时已经设置了 LV_OBJ_FLAG_CHECKABLE
        // 那么这里就可以检查 btn 当前的状态,达到打开或关闭下拉列表的目的
        // 这里的用法请参考 3_5_1 和 3_4_1
        if(lv_obj_has_state(btn, LV_STATE_CHECKED))
            lv_dropdown_open(dd);
        else
            lv_dropdown_close(dd);
    }
}

怎么说呢,反正就是当按键的值改变了,就打开下拉列表,不然就给它关上。

static void dd_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *obj = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        LV_LOG_USER("%d", lv_dropdown_get_selected(obj));       // 获取选项的索引值,从0开始
        char tmp_buf[32];
        lv_dropdown_get_selected_str(obj, tmp_buf, sizeof(tmp_buf)); // 获取选项的内容
        LV_LOG_USER("%s", tmp_buf);
    }
    else if(code == LV_EVENT_CLICKED)
    {
        // 改变下拉列表中列表的样式
        // 这些修改可以在初始化的时候就设置好,你也可以像下面这样动态地修改样式
        lv_obj_t * dd_list = lv_dropdown_get_list(obj);
        if(dd_list != NULL)
        {
            // 需要在 lv_conf.h 中打开宏 LV_FONT_MONTSERRAT_28,要使用其他内置字体同理
            // 注意:如果你初始化时使用了中文字库,并且设置了中文选项,这里设置之后内容将不能展示出来
            lv_obj_set_style_text_font(dd_list, &lv_font_montserrat_28, 0);

            // 修改列表的背景颜色
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xc43e1c), 0);
            //lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xc43e1c), LV_PART_MAIN); // 这样写和上面那个是一样的

            // 修改滚动条的样式
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_border_color(dd_list, lv_color_hex(0xcc3e1c), LV_PART_SCROLLBAR);

            // 修改当按下、选中或按下+选中选项时的样式
            // 这里只修改颜色,你还可以修改其他样式属性
            lv_obj_set_style_bg_color(dd_list, lv_color_hex(0xafbeac), LV_PART_SELECTED);

        }
    }
}

代码的注释写得很清楚

例程7_// 组件(widgets): 滚轮(lv_roller)的用法

// 通过其他部件选择
static void btn_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);
    lv_obj_t *roller  = lv_event_get_user_data(e);


    if(code == LV_EVENT_CLICKED) {
        uint32_t sel_opt = lv_roller_get_selected(roller);          // 获取当前选项的索引(位置)
        uint32_t total_opt = lv_roller_get_option_cnt(roller) - 1;  // 获取当前选项的总数,因为索引从 0 开始算,所以减一用于判断最后的选项

        if (sel_opt == total_opt)   sel_opt = 0;
        else                        sel_opt += 1;

        lv_roller_set_selected(roller, sel_opt, LV_ANIM_ON);
        lv_event_send(roller, LV_EVENT_VALUE_CHANGED, 0);           // 向 roller 发送 LV_EVENT_VALUE_CHANGED 事件
    }
}


// 滚轮的事件回调处理函数
static void roller_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *roller = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        LV_LOG_USER("%d", lv_roller_get_selected(roller));             // 获取被选中的选项的索引值,从0开始
        char tmp_buf[8];
        lv_roller_get_selected_str(roller, tmp_buf, sizeof(tmp_buf));  // 获取被选中的选项的内容
        LV_LOG_USER("%s", tmp_buf);
    }
}


void lv_100ask_demo_course_3_7_1(void)
{
#if 1
    // 使用物理按键控制,注意上面要包含 "lv_drivers/win32drv/win32drv.h",
    // LVGL按键控制,视频教程: https://www.bilibili.com/video/BV1Ya411r7K2?p=19
    // 创建一个组,稍后将需要使用键盘或编码器或按钮控制的部件(对象)添加进去,并且将输入设备和组关联
    // 如果将这个组设置为默认组,那么对于那些在创建时会添加到默认组的部件(对象)就可以省略 lv_group_add_obj()
    lv_group_t * g = lv_group_create();

    // 将上面创建的组设置为默认组
    // 如果稍后创建的部件(对象),使用默认组那必须要在其创建之前设置好默认组,否则不生效
    lv_group_set_default(g);

    // 将输入设备和组关联(使用前先打开上面注释掉的头文件)
    lv_indev_set_group(lv_win32_keypad_device_object, g);     // 键盘
    lv_indev_set_group(lv_win32_encoder_device_object, g);    // 鼠标上的滚轮(编码器)
#endif // 0

    /* 创建一个 lv_roller 部件(对象) */
    lv_obj_t * roller = lv_roller_create(lv_scr_act());    // 创建一个 lv_roller 部件(对象),他的父对象是活动屏幕对象

    // 将部件(对象)添加到组,如果设置了默认组,这里可以省略,因为 lv_roller 是 LV_OBJ_CLASS_GROUP_DEF_TRUE
    //lv_group_add_obj(g, roller);

#if 1
    lv_roller_set_options(roller, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", LV_ROLLER_MODE_NORMAL);   // 写法1:设置选项,索引从0开始
    //lv_roller_set_options(roller, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", LV_ROLLER_MODE_INFINITE); // 设置为可以无限滚动的模式
#if 0
    lv_roller_set_options(roller,
                          "1\n"
                          "2\n"
                          "3\n"
                          "4\n"
                          "5\n"
                          "6\n"
                          "7\n"
                          "8\n"
                          "9\n"
                          "10",
                          LV_ROLLER_MODE_NORMAL); // 写法2:设置选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)
#endif // 写法1:添加选项,索引从0开始
#endif // 写法2:添加选项(连续写两个双引号相当于将两者连起来,相当于上面的方法1)

    // 设置默认选中的选项
    lv_roller_set_selected(roller, 3, LV_ANIM_ON);

#if 0
    // 设置可见的选项个数(行数)
    // 如果滚轮的字体、行距、边框宽度等发生变化,则需要再次调用此函数以重新进行调整。
    lv_roller_set_visible_row_count(roller, 2);

#if 0
    // 可见行也可以通过调整高度设置,但是一般不会这么做
    // 正常是使用 lv_roller_set_visible_row_count 设置
    lv_obj_set_height(roller, 600);
#endif // 0
#endif // 1

    lv_obj_center(roller);                                    // 方法1:让对象居中,简洁
    //lv_obj_align(roller, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

#if 0
    // 修改滚轮所使用的字体(英文)
    lv_obj_set_style_text_font(roller, &lv_font_montserrat_22, LV_PART_MAIN);                 // 设置没有选中的选项的字体
    lv_obj_set_style_text_font(roller, &lv_font_montserrat_22, LV_PART_SELECTED);             // 设置选中的选项的字体
#endif // 0

#if 0
    // 修改滚轮所使用的字体(中文)
    LV_FONT_DECLARE(lv_font_source_han_sans_bold_14);   // 声明字体,可以放到函数外部
    lv_obj_set_style_text_font(roller, &lv_font_source_han_sans_bold_14, LV_PART_MAIN);                 // 设置没有选中的选项的字体
    lv_obj_set_style_text_font(roller, &lv_font_source_han_sans_bold_14, LV_PART_SELECTED);             // 设置选中的选项的字体
    lv_roller_set_options(roller, "一\n二\n三\n四\n五\n六\n七\n八\n九\n十", LV_ROLLER_MODE_NORMAL);     // 设置中文选项
#endif // 0

#if 0 
    // 改变选项中文字位置
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_LEFT, 0);   // 左对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_RIGHT, 0);  // 右对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_CENTER, 0); // 居中对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_AUTO, 0);   // 自动对齐
#endif // 0

    // 添加事件
    // 当我们滑动了滚轮中的选项列表时,会触发 LV_EVENT_VALUE_CHANGED 事件类型,这里接收所有的事件类型,在回调处理函数中再过滤处理
    lv_obj_add_event_cb(roller, roller_event_handler, LV_EVENT_ALL, NULL);

#if 1
    // 通过其他部件选择选项
    lv_obj_t * btn = lv_btn_create(lv_scr_act());
    lv_obj_align_to(btn, roller, LV_ALIGN_OUT_TOP_MID, 0, -10);
    lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_CLICKED , roller);
#endif // 1

}

后面这些部件虽然不难,但是整体的代码量都多了起来,我们也是像上一个例程那样慢慢来过一遍:

lv_group_t * g = lv_group_create();
lv_group_set_default(g);
lv_indev_set_group(lv_win32_keypad_device_object, g);     // 键盘
lv_indev_set_group(lv_win32_encoder_device_object, g);    // 鼠标上的滚轮(编码器)

将部件绑定物理设备

lv_obj_t * roller = lv_roller_create(lv_scr_act());    // 创建一个 lv_roller 部件(对象),他的父对象是活动屏幕对象

创建滚轮部件

lv_roller_set_options(roller, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", LV_ROLLER_MODE_NORMAL);   // 写法1:设置选项,索引从0开始
//lv_roller_set_options(roller, "1\n2\n3\n4\n5\n6\n7\n8\n9\n10", LV_ROLLER_MODE_INFINITE); // 设置为可以无限滚动的模式

设置滚动是否有结尾,第一种到10结束,第二种则是从10 => 1

lv_roller_set_selected(roller, 3, LV_ANIM_ON);

初始化默认选中的选项:4

lv_roller_set_visible_row_count(roller, 2);
//lv_obj_set_height(roller, 600);

设置最多可见多少个选项:2,下面注释的代码则是通过设置高度来设置选项可视度

lv_obj_align(roller, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

设置为居中

lv_obj_set_style_text_font(roller, &lv_font_montserrat_22, LV_PART_MAIN);                 // 设置没有选中的选项的字体
lv_obj_set_style_text_font(roller, &lv_font_montserrat_22, LV_PART_SELECTED);             // 设置选中的选项的字体

设置字体样式,可以看出来,字体样式,对象背景样式,位置等用的API的比较一致。并没有说有哪个部件有单独一个API

    // 改变选项中文字位置
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_LEFT, 0);   // 左对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_RIGHT, 0);  // 右对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_CENTER, 0); // 居中对齐
    //lv_obj_set_style_text_align(roller, LV_TEXT_ALIGN_AUTO, 0);   // 自动对齐

更改文字位置

lv_obj_add_event_cb(roller, roller_event_handler, LV_EVENT_ALL, NULL);
// 滚轮的事件回调处理函数
static void roller_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *roller = lv_event_get_target(e);

    if (code == LV_EVENT_VALUE_CHANGED)
    {
        LV_LOG_USER("%d", lv_roller_get_selected(roller));             // 获取被选中的选项的索引值,从0开始
        char tmp_buf[8];
        lv_roller_get_selected_str(roller, tmp_buf, sizeof(tmp_buf));  // 获取被选中的选项的内容
        LV_LOG_USER("%s", tmp_buf);
    }
}

设置滑轮的回调函数,回调函数主要是通过用户终端打印出目前选项的索引及内容

// 通过其他部件选择选项
lv_obj_t * btn = lv_btn_create(lv_scr_act());
lv_obj_align_to(btn, roller, LV_ALIGN_OUT_TOP_MID, 0, -10);
lv_obj_add_event_cb(btn, btn_event_handler, LV_EVENT_CLICKED , roller);

设置一个按钮部件来控制滑轮部件

// 通过其他部件选择
static void btn_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t *btn = lv_event_get_target(e);
    lv_obj_t *roller  = lv_event_get_user_data(e);


    if(code == LV_EVENT_CLICKED) {
        uint32_t sel_opt = lv_roller_get_selected(roller);          // 获取当前选项的索引(位置)
        uint32_t total_opt = lv_roller_get_option_cnt(roller) - 1;  // 获取当前选项的总数,因为索引从 0 开始算,所以减一用于判断最后的选项

        if (sel_opt == total_opt)   sel_opt = 0;
        else                        sel_opt += 1;

        lv_roller_set_selected(roller, sel_opt, LV_ANIM_ON);
        lv_event_send(roller, LV_EVENT_VALUE_CHANGED, 0);           // 向 roller 发送 LV_EVENT_VALUE_CHANGED 事件
    }
}

该按钮做的主要是每按下一次,则选到下一个选项。

闭门造轮(LVGL_2)_第13张图片

例程8_// 组件(widgets): 进度条(lv_bar)的用法

static void bar_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);        // 获取触发事件的部件(对象)
	lv_obj_t * label = lv_event_get_user_data(e);	// 获取事件传递的用户数据(user_data)
    lv_event_code_t code = lv_event_get_code(e);    // 获取当前部件(对象)触发的事件代码

    switch(code){
        case LV_EVENT_CLICKED:
            LV_LOG_USER("LV_EVENT_CLICKED\n");
			if (lv_bar_get_value(obj) == lv_bar_get_max_value(obj))
				lv_bar_set_value(obj, 0, LV_ANIM_ON);
			else
				lv_bar_set_value(obj, 30, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(obj));
            break;
		case LV_EVENT_PRESSING:
            LV_LOG_USER("LV_EVENT_PRESSING\n");
			lv_bar_set_value(obj, lv_bar_get_value(obj)+1, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(obj));
            break;
		/* ...... */
		/*请尝试添加更多的case吧*/
        default:
            //LV_LOG_USER("NONE\n");
            break;
    }
}


void lv_100ask_demo_course_3_8_1(void)
{
	// 创建一个 bar 组件(对象),他的父对象是活动屏幕对象
    lv_obj_t *bar = lv_bar_create(lv_scr_act());
	LV_LOG_USER("lv_bar_get_value(bar) %d", lv_bar_get_value(bar));

	/* 设置大小 */
	// 可以不设置,使用默认大小
	//lv_obj_set_size(bar, 200, 30);

	// 当设置进度条的宽度小于其高度,就可以创建出垂直摆放的进度条。
	//lv_obj_set_size(bar, 30, 200);

	/* 设置位置 */
	lv_obj_center(bar);                                    // 方法1:让对象居中,简洁
    //lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

	/* 设置进度条的模式(modes) */
	/* 进度条有三种模式*/
#if 0
	// 1.normal模式,如果没有设置模式默认是这个模式
	lv_bar_set_mode(bar, LV_BAR_MODE_NORMAL);
	lv_bar_set_range(bar, 0, 100); 				// 如果不设置,默认是(0-100)
#endif

#if 0
	// 2.symmetrical模式,这个模式下可以指定负的最小范围。但是只能从零值到当前值绘制指示器。
	lv_bar_set_mode(bar, LV_BAR_MODE_SYMMETRICAL);
	lv_bar_set_range(bar, -100, 100); 			// 这个模式下可以指定负的最小范围
	lv_bar_set_value(bar, 50, LV_ANIM_ON);		// 设置结束值(大于0)
	//lv_bar_set_value(bar, -50, LV_ANIM_ON);	// 设置结束值(小于0)
#endif

#if 0
	// 3.range模式,这个模式下也可以指定负的最小范围。这样进度条的起始值可以不是0,而是你指定的数值,这样设置的起始值必须小于结束值。
	lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);
	lv_bar_set_range(bar, -100, 100);				// 这个模式下可以指定负的最小范围
	lv_bar_set_value(bar, 50, LV_ANIM_ON);			// 设置结束值
	lv_bar_set_start_value(bar, -90, LV_ANIM_ON);	// 设置起始值,注意必须小于结束值
#endif

	/* 设置样式 */
	// 假如 'lv_bar_set_value' 或 'lv_bar_set_start_value'
	// 设置了 LV_ANIM_ON,那么这里可以调整动画的时间
	lv_obj_set_style_anim_time(bar, 1000, LV_PART_MAIN);

	// 设置当被按下时,指示器部分的背景颜色
	//lv_obj_set_style_bg_color(bar, lv_color_hex(0xbdddba), LV_PART_INDICATOR | LV_STATE_PRESSED);

	// 设置默认状态下,指示器部分的背景颜色
	//lv_obj_set_style_bg_color(bar, lv_color_hex(0x1e1e1e), LV_PART_INDICATOR | LV_STATE_DEFAULT);

	// 设置指示器的延申方向
	// 注意 bar 设置为 symmetrical 模式时显示不出来的情况,需要反过来设置数值
	//lv_obj_set_style_base_dir(bar, LV_BASE_DIR_RTL, LV_PART_MAIN);

	lv_obj_t * label = lv_label_create(lv_scr_act());
	lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(bar));
	lv_obj_align_to(label, bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);

	// 设置事件处理回调函数,接收所有的事件类型
	lv_obj_add_event_cb(bar, bar_event_cb, LV_EVENT_ALL, label);
}
lv_obj_t *bar = lv_bar_create(lv_scr_act());
LV_LOG_USER("lv_bar_get_value(bar) %d", lv_bar_get_value(bar));

创建一个进度条部件对象

/* 设置大小 */
// 可以不设置,使用默认大小
//lv_obj_set_size(bar, 200, 30);

设置进度条的长宽

lv_obj_align(bar, LV_ALIGN_CENTER, 0, 0);            // 方法2:让对象居中,较为灵活

设置进度条的位置

	/* 设置进度条的模式(modes) */
	/* 进度条有三种模式*/
#if 0
	// 1.normal模式,如果没有设置模式默认是这个模式
	lv_bar_set_mode(bar, LV_BAR_MODE_NORMAL);
	lv_bar_set_range(bar, 0, 100); 				// 如果不设置,默认是(0-100)
#endif

#if 0
	// 2.symmetrical模式,这个模式下可以指定负的最小范围。但是只能从零值到当前值绘制指示器。
	lv_bar_set_mode(bar, LV_BAR_MODE_SYMMETRICAL);
	lv_bar_set_range(bar, -100, 100); 			// 这个模式下可以指定负的最小范围
	lv_bar_set_value(bar, 50, LV_ANIM_ON);		// 设置右半轴初始值(大于0)
	lv_bar_set_value(bar, -50, LV_ANIM_ON);	    // 设置左半轴初始值(小于0)
#endif

#if 0
	// 3.range模式,这个模式下也可以指定负的最小范围。这样进度条的起始值可以不是0,而是你指定的数值,这样设置的起始值必须小于结束值。
	lv_bar_set_mode(bar, LV_BAR_MODE_RANGE);
	lv_bar_set_range(bar, -100, 100);				// 这个模式下可以指定负的最小范围
	lv_bar_set_value(bar, 50, LV_ANIM_ON);			// 设置结束值(大于0)
	lv_bar_set_start_value(bar, -90, LV_ANIM_ON);	// 设置起始值,注意必须小于结束值
#endif

三种模式,三种模式都自己体验下就懂了。

lv_obj_set_style_anim_time(bar, 1000, LV_PART_MAIN);

该函数的作用是将进度条控件(bar)的主要(LV_PART_MAIN)样式动画效果的持续时间设置为1000毫秒。

lv_obj_set_style_bg_color(bar, lv_color_hex(0xbdddba), LV_PART_INDICATOR | LV_STATE_PRESSED);

更改点击后进度条的颜色:(原本是蓝色,改成了青色)

闭门造轮(LVGL_2)_第14张图片

lv_obj_set_style_bg_color(bar, lv_color_hex(0x1e1e1e), LV_PART_INDICATOR | LV_STATE_DEFAULT);

设置进度条的默认颜色为黑色

lv_obj_set_style_base_dir(bar, LV_BASE_DIR_RTL, LV_PART_MAIN);

设置进度条反向增加:

闭门造轮(LVGL_2)_第15张图片

lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(bar));
lv_obj_align_to(label, bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);

设置一个label标签,放置在进度条中部下方,该标签值为进度条的值。

lv_obj_add_event_cb(bar, bar_event_cb, LV_EVENT_ALL, label);
static void bar_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);        // 获取触发事件的部件(对象)
	lv_obj_t * label = lv_event_get_user_data(e);	// 获取事件传递的用户数据(user_data)
    lv_event_code_t code = lv_event_get_code(e);    // 获取当前部件(对象)触发的事件代码

    switch(code){
        case LV_EVENT_CLICKED:
            LV_LOG_USER("LV_EVENT_CLICKED\n");
			if (lv_bar_get_value(obj) == lv_bar_get_max_value(obj))
				lv_bar_set_value(obj, 0, LV_ANIM_ON);
			else
				lv_bar_set_value(obj, 30, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(obj));
            break;
		case LV_EVENT_PRESSING:
            LV_LOG_USER("LV_EVENT_PRESSING\n");
			lv_bar_set_value(obj, lv_bar_get_value(obj)+1, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_bar_get_value(obj));
            break;
		/* ...... */
		/*请尝试添加更多的case吧*/
        default:
            //LV_LOG_USER("NONE\n");
            break;
    }
}

设置回调函数,这个回调函数内有两个操作方式,1.按一下,进度条开始加载,加载到30就停下来,2.按住进度条,最高可到100

例程9_// 组件(widgets): 进度条(lv_slider)的用法

void lv_100ask_demo_course_3_9_1(void)
{

	/* 关闭这个宏开关后,可以尝试后面的 "slider 小实战": test_slider() */
#if 1
	// 创建一个 slider 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t *slider = lv_slider_create(lv_scr_act());
	LV_LOG_USER("lv_slider_get_value(slider) %d", lv_slider_get_value(slider));

	/* 设置大小 */
	// 可以不设置,使用默认大小
	//lv_obj_set_size(slider, 200, 50);

	// 当设置进度条的宽度小于其高度,就可以创建出垂直摆放的进度条。
	//lv_obj_set_size(slider, 50, 200);

	/* 设置位置 */
	lv_obj_center(slider); 								   // 方法1:让对象居中,简洁
	//lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0); 		   // 方法2:让对象居中,较为灵活


	/* 设置进度条的模式(modes) */
	/* 进度条有三种模式*/
#if 0
	// 1.normal模式,如果没有设置模式默认是这个模式
	lv_slider_set_mode(slider, LV_BAR_MODE_NORMAL);
	lv_slider_set_range(slider, 0, 100);				// 如果不设置,默认是(0-100)
#endif

#if 0
	// 2.symmetrical模式,这个模式下可以指定负的最小范围。但是只能从零值到当前值绘制指示器。
	lv_slider_set_mode(slider, LV_BAR_MODE_SYMMETRICAL);
	lv_slider_set_range(slider, -100, 100);			// 这个模式下可以指定负的最小范围
	//lv_slider_set_value(slider, 50, LV_ANIM_ON);		// 设置结束值(大于0)
	lv_slider_set_value(slider, -50, LV_ANIM_ON);	// 设置结束值(小于0)
#endif

#if 0
	// 3.range模式,这个模式下也可以指定负的最小范围。这样进度条的起始值可以不是0,而是你指定的数值,这样设置的起始值必须小于结束值。
	lv_slider_set_mode(slider, LV_BAR_MODE_RANGE);
	lv_slider_set_range(slider, -100, 100);				// 这个模式下可以指定负的最小范围
	lv_slider_set_value(slider, 50, LV_ANIM_ON);			// 设置结束值
	lv_slider_set_left_value(slider, -90, LV_ANIM_ON);	// 设置起始值,注意必须小于结束值
#endif

#if 0
	/*Knob-only mode(仅旋钮模式)*/
	// 这个模式下只能通过拖动滑动条的旋钮(PART KNOB)来调整滑动条的数值
	lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST);
#endif

#if 0
	/* 设置指示器的延申方向 */
	// 注意如果 slider 同时设置为 symmetrical 模式时会有显示不出来的情况,此时需要反过来设置数值
	lv_obj_set_style_base_dir(slider, LV_BASE_DIR_RTL, LV_PART_MAIN);
#endif

#if 0
	/* 设置样式 */
	// 假如 'lv_slider_set_value' 或 'lv_slider_set_start_value'
	// 设置了 LV_ANIM_ON,那么这里可以调整动画的时间
	lv_obj_set_style_anim_time(slider, 1000, LV_PART_MAIN);

	lv_obj_set_style_bg_color(slider, lv_color_hex(0xff0000), LV_PART_MAIN);

	// 设置当被按下时,指示器部分的背景颜色
	lv_obj_set_style_bg_color(slider, lv_color_hex(0xbdddba), LV_PART_INDICATOR | LV_STATE_PRESSED);

	// 设置默认状态下,指示器部分的背景颜色
	lv_obj_set_style_bg_color(slider, lv_color_hex(0x1e1e1e), LV_PART_INDICATOR | LV_STATE_DEFAULT);

	lv_obj_set_style_bg_opa(slider, LV_OPA_100, 0);
	lv_obj_set_style_bg_color(slider, lv_color_hex(0xbdddba), LV_PART_KNOB | LV_STATE_PRESSED);
	lv_obj_set_style_bg_color(slider, lv_color_hex(0x1e1e1e), LV_PART_KNOB | LV_STATE_DEFAULT);
#endif


#if 0
	/* 创建一个label 实时展示滑动条当前的数值 */
	lv_obj_t * label = lv_label_create(lv_scr_act());
	lv_label_set_text_fmt(label, "%d%%", lv_slider_get_value(slider));
	lv_obj_align_to(label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);

	// 设置事件处理回调函数,接收所有的事件类型
	lv_obj_add_event_cb(slider, slider_event_cb, LV_EVENT_ALL, label);
#endif	

#endif

	/* slider 小实战,打开下面的宏开关前,请先关闭上面的宏开关 */
	// 视频教程: https://www.bilibili.com/video/BV1Ya411r7K2?p=32
#if 0
	// 共享样式初始化之后,就可以给其他部件使用
	// 如果要创建多个组件,并且他们的样式都是一样的,
	// 那么,使用同一个共享样式就可以达到节省内存的目的
	slider_style_init();

	// 创建并初始化多个slider
	test1_slider();
	test2_slider();

#endif

}

/**********************
 *   STATIC FUNCTIONS
 **********************/

static void slider_style_init(void)
{
	/* 初始化样式 */
	lv_style_init(&style_part_main);
	lv_style_init(&style_part_knob);
	lv_style_init(&style_part_indicator);

	/* 设置 PART MAIN 样式 */
	lv_style_set_radius(&style_part_main, 15);			// 设置四个角的圆角
	lv_style_set_bg_color(&style_part_main, 
						  lv_color_hex(0xc43e1c));		// 设置背景颜色
	lv_style_set_pad_top(&style_part_main, -2); 		// 设置顶部(top)的填充(top)大小
	lv_style_set_pad_bottom(&style_part_main, -2);		// 设置底部部(bottom)的填充(top)大小
	//lv_style_set_bg_opa(&style_part_main, LV_OPA_100);	// 设置背景透明度

	/* 设置 PART KNOB 样式 */
	// 将 knob 部分整个设置为透明,就能达到去除旋钮的效果
	// set_opa是设置不透明度,设置不透明度为0就是完全透明
	lv_style_set_opa(&style_part_knob, LV_OPA_0);

	/* 设置 PART INDICATOR 样式 */
	lv_style_set_radius(&style_part_indicator, 0);		// 设置四个角的圆角
	lv_style_set_bg_color(&style_part_indicator,
						  lv_color_hex(0xffffff));		// 设置背景颜色

}
static void test1_slider(void)
{
	// 创建一个 slider 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t *slider = lv_slider_create(lv_scr_act());

	/* 设置位置 */
	lv_obj_center(slider); 								// 方法1:让对象居中,简洁
	//lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0); 		// 方法2:让对象居中,较为灵活

	/*调整大小,让 slider 垂直摆放  */
	lv_obj_set_size(slider, 60, 150);


	/* 将样式应用到 slider */
	// 将保存在 style_part_main 中的样式应用到
	// slider 的 LV_PART_MAIN 上
	lv_obj_add_style(slider, &style_part_main, LV_PART_MAIN);

	// 将保存在 style_part_knob 中的样式应用到
	// slider 的 LV_PART_KNOB 上
	lv_obj_add_style(slider, &style_part_knob, LV_PART_KNOB);

	// 将保存在 style_part_indicator 中的样式应用到
	// slider 的 LV_PART_INDICATOR 上
	lv_obj_add_style(slider, &style_part_indicator, LV_PART_INDICATOR);


	/* 在 slider 内部放一个小图标,用来表明slider的作用 */
	// 这里使用 lvgl 的内置符号(方便、节省内存),可以使用img展示。
	// lvgl内置符号: http://lvgl.100ask.net/8.2/overview/font.html#special-fonts
	lv_obj_t *label = lv_label_create(slider);
	lv_label_set_text(label, LV_SYMBOL_VOLUME_MAX);

	// 在lvgl中内置符号可以像 text 那样使用,lvgl 内置了很多不一样的字体(ASCII),
	// 使用不同尺寸的内置字体就能展示不一样大小的 text ,默认是:lv_font_montserrat_14
	// 需要设置内置字体,请查看: lv_conf.h 中的 LV_FONT_MONTSERRAT_...
	lv_obj_set_style_text_font(label, &lv_font_montserrat_20, 0);
	lv_obj_set_style_text_color(label, lv_color_hex(0xac8477), 0);
	lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -20);

}



static void test2_slider(void)
{
	// 创建一个 slider 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t *slider = lv_slider_create(lv_scr_act());

	/* 设置位置 */
	//lv_obj_center(slider); 								// 方法1:让对象居中,简洁
	//lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0); 		// 方法2:让对象居中,较为灵活

	/*调整大小,让 slider 垂直摆放  */
	lv_obj_set_size(slider, 60, 150);


	/* 将样式应用到 slider */
	// 将保存在 style_part_main 中的样式应用到
	// slider 的 LV_PART_MAIN 上
	lv_obj_add_style(slider, &style_part_main, LV_PART_MAIN);

	// 将保存在 style_part_knob 中的样式应用到
	// slider 的 LV_PART_KNOB 上
	lv_obj_add_style(slider, &style_part_knob, LV_PART_KNOB);

	// 将保存在 style_part_indicator 中的样式应用到
	// slider 的 LV_PART_INDICATOR 上
	lv_obj_add_style(slider, &style_part_indicator, LV_PART_INDICATOR);


	/* 在 slider 内部放一个小图标,用来表明slider的作用 */
	// 这里使用 lvgl 的内置符号(方便、节省内存),可以使用img展示。
	// lvgl内置符号: http://lvgl.100ask.net/8.2/overview/font.html#special-fonts
	lv_obj_t *label = lv_label_create(slider);
	lv_label_set_text(label, LV_SYMBOL_VOLUME_MAX);

	// 在lvgl中内置符号可以像 text 那样使用,lvgl 内置了很多不一样的字体(ASCII),
	// 使用不同尺寸的内置字体就能展示不一样大小的 text ,默认是:lv_font_montserrat_14
	// 需要设置内置字体,请查看: lv_conf.h 中的 LV_FONT_MONTSERRAT_...
	lv_obj_set_style_text_font(label, &lv_font_montserrat_20, 0);
	lv_obj_set_style_text_color(label, lv_color_hex(0xac8477), 0);
	lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -20);

}

static void slider_event_cb(lv_event_t * e)
{
    lv_obj_t * obj = lv_event_get_target(e);        // 获取触发事件的部件(对象)
	lv_obj_t * label = lv_event_get_user_data(e);	// 获取事件传递的用户数据(user_data)
    lv_event_code_t code = lv_event_get_code(e);    // 获取当前部件(对象)触发的事件代码

    switch(code){
        case LV_EVENT_CLICKED:
            LV_LOG_USER("LV_EVENT_CLICKED\n");
			if (lv_slider_get_value(obj) == lv_slider_get_max_value(obj))
				lv_slider_set_value(obj, 0, LV_ANIM_ON);
			else
				lv_slider_set_value(obj, 30, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_slider_get_value(obj));
            break;
		case LV_EVENT_PRESSING:
            LV_LOG_USER("LV_EVENT_PRESSING\n");
			lv_slider_set_value(obj, lv_slider_get_value(obj)+1, LV_ANIM_ON);
			lv_label_set_text_fmt(label, "%d%%", lv_slider_get_value(obj));
            break;
		/* ...... */
		/*请尝试添加更多的case吧*/
		case LV_EVENT_VALUE_CHANGED:
			//lv_label_set_text_fmt(label, "%d%%", lv_slider_get_value(obj));
			LV_LOG_USER("LV_EVENT_VALUE_CHANGED\n");
			break;
        default:
            //LV_LOG_USER("OTHERS\n");
            break;
    }
}

这部分代码在之前的例程出现过,但较为简单,这里的例程提供得更详细。

lv_obj_add_flag(slider, LV_OBJ_FLAG_ADV_HITTEST);

只能通过旋钮来控制滑杆

这里主要讲一下一个实例的项目:(现象如下:) 

闭门造轮(LVGL_2)_第16张图片

slider_style_init();
static void slider_style_init(void)
{
	/* 初始化样式 */
	lv_style_init(&style_part_main);
	lv_style_init(&style_part_knob);
	lv_style_init(&style_part_indicator);

	/* 设置 PART MAIN 样式 */
	lv_style_set_radius(&style_part_main, 15);			// 设置四个角的圆角
	lv_style_set_bg_color(&style_part_main,
						  lv_color_hex(0xc43e1c));		// 设置背景颜色
	lv_style_set_pad_top(&style_part_main, -2); 		// 设置顶部(top)的填充(top)大小
	lv_style_set_pad_bottom(&style_part_main, -2);		// 设置底部部(bottom)的填充(top)大小
	//lv_style_set_bg_opa(&style_part_main, LV_OPA_100);	// 设置背景透明度

	/* 设置 PART KNOB 样式 */
	// 将 knob 部分整个设置为透明,就能达到去除旋钮的效果
	// set_opa是设置不透明度,设置不透明度为0就是完全透明
	lv_style_set_opa(&style_part_knob, LV_OPA_0);

	/* 设置 PART INDICATOR 样式 */
	lv_style_set_radius(&style_part_indicator, 0);		// 设置四个角的圆角
	lv_style_set_bg_color(&style_part_indicator,
						  lv_color_hex(0xffffff));		// 设置背景颜色

}

滑杆的初始化函数内主要设置的是滑杆部件的样式,不解释,其实就是UI一样的东西。

test1_slider();
test2_slider();
static void test1_slider(void)
{
	// 创建一个 slider 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t *slider = lv_slider_create(lv_scr_act());

	/* 设置位置 */
	lv_obj_center(slider); 								// 方法1:让对象居中,简洁
	//lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0); 		// 方法2:让对象居中,较为灵活

	/*调整大小,让 slider 垂直摆放  */
	lv_obj_set_size(slider, 60, 150);


	/* 将样式应用到 slider */
	// 将保存在 style_part_main 中的样式应用到
	// slider 的 LV_PART_MAIN 上
	lv_obj_add_style(slider, &style_part_main, LV_PART_MAIN);

	// 将保存在 style_part_knob 中的样式应用到
	// slider 的 LV_PART_KNOB 上
	lv_obj_add_style(slider, &style_part_knob, LV_PART_KNOB);

	// 将保存在 style_part_indicator 中的样式应用到
	// slider 的 LV_PART_INDICATOR 上
	lv_obj_add_style(slider, &style_part_indicator, LV_PART_INDICATOR);


	/* 在 slider 内部放一个小图标,用来表明slider的作用 */
	// 这里使用 lvgl 的内置符号(方便、节省内存),可以使用img展示。
	// lvgl内置符号: http://lvgl.100ask.net/8.2/overview/font.html#special-fonts
	lv_obj_t *label = lv_label_create(slider);
	lv_label_set_text(label, LV_SYMBOL_VOLUME_MAX);

	// 在lvgl中内置符号可以像 text 那样使用,lvgl 内置了很多不一样的字体(ASCII),
	// 使用不同尺寸的内置字体就能展示不一样大小的 text ,默认是:lv_font_montserrat_14
	// 需要设置内置字体,请查看: lv_conf.h 中的 LV_FONT_MONTSERRAT_...
	lv_obj_set_style_text_font(label, &lv_font_montserrat_20, 0);
	lv_obj_set_style_text_color(label, lv_color_hex(0xac8477), 0);
	lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -20);

}



static void test2_slider(void)
{
	// 创建一个 slider 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t *slider = lv_slider_create(lv_scr_act());

	/* 设置位置 */
	//lv_obj_center(slider); 								// 方法1:让对象居中,简洁
	//lv_obj_align(slider, LV_ALIGN_CENTER, 0, 0); 		// 方法2:让对象居中,较为灵活

	/*调整大小,让 slider 垂直摆放  */
	lv_obj_set_size(slider, 60, 150);


	/* 将样式应用到 slider */
	// 将保存在 style_part_main 中的样式应用到
	// slider 的 LV_PART_MAIN 上
	lv_obj_add_style(slider, &style_part_main, LV_PART_MAIN);

	// 将保存在 style_part_knob 中的样式应用到
	// slider 的 LV_PART_KNOB 上
	lv_obj_add_style(slider, &style_part_knob, LV_PART_KNOB);

	// 将保存在 style_part_indicator 中的样式应用到
	// slider 的 LV_PART_INDICATOR 上
	lv_obj_add_style(slider, &style_part_indicator, LV_PART_INDICATOR);


	/* 在 slider 内部放一个小图标,用来表明slider的作用 */
	// 这里使用 lvgl 的内置符号(方便、节省内存),可以使用img展示。
	// lvgl内置符号: http://lvgl.100ask.net/8.2/overview/font.html#special-fonts
	lv_obj_t *label = lv_label_create(slider);
	lv_label_set_text(label, LV_SYMBOL_VOLUME_MAX);

	// 在lvgl中内置符号可以像 text 那样使用,lvgl 内置了很多不一样的字体(ASCII),
	// 使用不同尺寸的内置字体就能展示不一样大小的 text ,默认是:lv_font_montserrat_14
	// 需要设置内置字体,请查看: lv_conf.h 中的 LV_FONT_MONTSERRAT_...
	lv_obj_set_style_text_font(label, &lv_font_montserrat_20, 0);
	lv_obj_set_style_text_color(label, lv_color_hex(0xac8477), 0);
	lv_obj_align(label, LV_ALIGN_BOTTOM_MID, 0, -20);

}

例程10_// 组件(widgets): 圆弧(lv_arc)的用法

void lv_100ask_demo_course_3_10_1(void)
{
#if 1
    // 创建一个 arc 组件(对象),他的父对象是活动屏幕对象
	lv_obj_t * arc = lv_arc_create(lv_scr_act());

	/* 设置大小 */
	// 对于 arc 来说,影响弧长的因素有两个:角度和半径
	// 可以不设置,使用默认大小
	//lv_obj_set_size(arc, 400, 400);

	/* 调整位置 */
	lv_obj_center(arc);								   // 方法1:让对象居中,简洁
	//lv_obj_align(arc, LV_ALIGN_CENTER, 0, 0);		   // 方法2:让对象居中,较为灵活

	/* 设置 arc 的当前值 */
	/*
	 *  如果不设置,默认值是 INT16_MIN 
	 *  也就是起码要在arc的数值被改变一次之后,再获取arc的当前值使用
	 */
	//lv_arc_set_value(arc, 60);


	/* 设置arc的模式(modes) */
	/* arc 有三种模式 */
#if 1
	// 普通模式。指示器从最小值绘制到当前值。
	// 如果不设置模式,默认就是此模式
	lv_arc_set_mode(arc, LV_ARC_MODE_NORMAL);

	// 反向模式。指示器从最大值到当前值逆时针绘制。
	//lv_arc_set_mode(arc, LV_ARC_MODE_REVERSE);
	
	// 对称模式。指示器从中间点绘制到当前值。
	//lv_arc_set_mode(arc, LV_ARC_MODE_SYMMETRICAL);
#endif

	/* 设置变化率 */
	/* 
	 *  当圆弧被按下时,当前值将根据设置的变化率以有限的速度绘制出来。
	 *  变化率的单位是 “度/秒”
	 *  默认是 720°/s
	 */
	//lv_arc_set_change_rate(arc, 360);


	/* 设置背景弧和前景弧 */
	/* 零度位于对象的中间右侧(3 点钟方向),并且度数沿顺时针方向增加。*/
#if 0
	/* 设置背景弧 */
	/* 如果不设置,默认为         (135°-45°) */
	/* 
     * 背景弧就是我们看到的呈现灰色的弧,
	 * 其决定arc的绘制范围,同时也限制了前景弧的绘制范围
	 */
	// 设置背景弧的起始角度(位置)
	lv_arc_set_bg_start_angle(arc, 0);

	// 设置背景弧的结束角度(位置)	
	lv_arc_set_bg_end_angle(arc, 180);

	// 同时设置背景弧的 起始+结束 角度	
	lv_arc_set_bg_angles(arc, 0, 180);


	/* 设置前景弧 */
	/* 如果不设置,默认为       (135°-270°) */
	/* 
	 *  前置弧就是我们看到的呈现蓝色的弧,
	 *  其直接与用户进行交互,绘制范围受限于背景弧
	 */
	// 设置前景弧的起始角度(位置)
	lv_arc_set_start_angle(arc, 0);

	// 设置前景弧的结束角度(位置)	
	lv_arc_set_end_angle(arc, 180);

	// 同时设置前景弧的 起始+结束 角度	
	lv_arc_set_angles(arc, 0, 180);
	
#endif

	// 在设置好的前景弧和背景弧的基础上,
	// 将其整个旋转一个指定的角度
	lv_arc_set_rotation(arc, 90);

#if 0
	// 让arc不可点击
	// 这个时候指定通过 lv_arc_set_value 改变arc
	// 可以用在加载页面作为 loader 提示
	//lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);

	// 让arc恢复可以点击的属性
	lv_obj_add_flag(arc, LV_OBJ_FLAG_CLICKABLE);
#endif

#if 0
	// 去除指示器部分的样式,相当于让指示器部分整个不存在
	lv_obj_remove_style(arc, NULL, LV_PART_INDICATOR);

	// 去除旋钮部分的样式,相当于让选秀部分整个不存在
	lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
#endif


#if 1
	/* 
	 *  创建一个label实时更新展示arc的当前值
	 *  同时在事件处理回调函数中在
	 *  控制台打印arc的当前值
	 */
	lv_label_t * label = lv_label_create(lv_scr_act());
	lv_obj_align_to(label, arc, LV_ALIGN_OUT_BOTTOM_MID, 0, 0);
	
	lv_obj_add_event_cb(arc, arc_event_cb, LV_EVENT_VALUE_CHANGED, label);
#endif

#endif	

#if 0
	lv_100ask_arc_test();
#endif

}


/**********************
 *   STATIC FUNCTIONS
 **********************/
static void arc_event_cb(lv_event_t * e)
{
	lv_obj_t * arc = lv_event_get_target(e);
	lv_obj_t * label = (lv_obj_t *)lv_event_get_user_data(e);
	int16_t value = lv_arc_get_value(arc);
	
	lv_label_set_text_fmt(label, "%d°", value);
	LV_LOG_USER("lv_arc_get_value(arc) = %d", value);
}

LV_FONT_DECLARE(lv_100ask_font_source_han_mono_extra_light_32);

static void lv_100ask_arc_test(void)
{
	/* 第1层:以屏幕对象为容器(parent),创建一个arc,其成为后面创建的组件的容器(parent) */
	lv_obj_t * arc_tmp = lv_arc_create(lv_scr_act());
	lv_obj_center(arc_tmp);
	lv_obj_set_size(arc_tmp, 350, 350);
	lv_arc_set_range(arc_tmp, 15, 35);
	lv_arc_set_value(arc_tmp, 23);
	lv_arc_set_bg_angles(arc_tmp, 120, 60);

	lv_obj_set_style_radius(arc_tmp, 360, LV_PART_MAIN);							// 设置part main在默认状态下的圆角		
	lv_obj_set_style_bg_opa(arc_tmp, LV_OPA_COVER, LV_PART_MAIN);  					// 设置part main在默认状态下的背景透明度
	lv_obj_set_style_bg_color(arc_tmp, lv_color_make(30, 35, 45), LV_PART_MAIN); 	// 设置part main在默认状态下的背景颜色
	lv_obj_set_style_pad_all(arc_tmp, 10, LV_PART_MAIN);							// 设置part main在默认状态下的填充/间隔/pad
	lv_obj_set_style_arc_color(arc_tmp, lv_color_make(15, 18, 21), LV_PART_MAIN); 	// 设置背景弧在默认状态下的颜色
	lv_obj_set_style_arc_width(arc_tmp, 15, LV_PART_MAIN);							// 设置背景弧在默认状态下的宽度
	lv_obj_set_style_arc_color(arc_tmp, lv_color_make(54, 185, 246), LV_PART_INDICATOR);	// 设置前景弧在默认状态下的颜色
	lv_obj_set_style_arc_width(arc_tmp, 15, LV_PART_INDICATOR);						// 设置前景弧在默认状态下的宽度

	// 去除旋钮部分的样式,相当于让选秀部分整个不存在
	lv_obj_remove_style(arc_tmp, NULL, LV_PART_KNOB);		// 方法1,去除arc组件中整个PART_KNOB的样式
	lv_obj_set_style_opa(arc_tmp, LV_OPA_0, LV_PART_KNOB);  // 方法2,让PART_KNOB完全透明

	/* 第2层:以前面的组件为容器(parent),创建一个面板,用来突出层次感,并成为后面创建的组件的容器(parent) */
	lv_obj_t * panel3 = lv_obj_create(arc_tmp);
	lv_obj_set_size(panel3, 280, 280);
	lv_obj_center(panel3);

	lv_obj_set_style_radius(panel3, 360, LV_PART_MAIN);								// 设置part main在默认状态下的圆角		
	lv_obj_set_style_bg_color(panel3, lv_color_make(100, 100, 100), LV_PART_MAIN);	// 设置part main在默认状态下的背景颜色
	lv_obj_set_style_bg_grad_color(panel3, lv_color_make(60, 65, 75), LV_PART_MAIN);// 设置part main在默认状态下的背景渐变颜色
	lv_obj_set_style_bg_grad_dir(panel3, LV_GRAD_DIR_VER, LV_PART_MAIN);			// 设置part main在默认状态下的背景渐变方向
	lv_obj_set_style_border_color(panel3, lv_color_make(45, 50, 60), LV_PART_MAIN); // 设置part main在默认状态下的边框宽度
	lv_obj_set_style_arc_width(panel3, 2, LV_PART_MAIN);							
	lv_obj_set_style_shadow_color(panel3, lv_color_make(5, 10, 15), LV_PART_MAIN);	// 设置part main在默认状态下的阴影颜色
	lv_obj_set_style_shadow_width(panel3, 80, LV_PART_MAIN);						// 设置part main在默认状态下的阴影宽度
	lv_obj_set_style_shadow_spread(panel3, 0, LV_PART_MAIN);						// 设置part main在默认状态下的阴影扩散范围
	lv_obj_set_style_shadow_ofs_x(panel3, 0, LV_PART_MAIN);							// 设置part main在默认状态下的阴影在x轴上的偏移
	lv_obj_set_style_shadow_ofs_y(panel3, 30, LV_PART_MAIN);						// 设置part main在默认状态下的阴影在y轴上的偏移

	/* 第3层:以前面的组件为容器(parent),再创建一个面板,用来突出层次感,同时成为展示当前数值组件的容器(parent) */
	lv_obj_t * panel_temp_value = lv_obj_create(panel3);
	lv_obj_set_size(panel_temp_value, 200, 200);
	lv_obj_center(panel_temp_value);

	lv_obj_set_style_radius(panel_temp_value, 360, LV_PART_MAIN);								// 设置part main在默认状态下的圆角		
	lv_obj_set_style_bg_color(panel_temp_value, lv_color_make(12, 25, 30), LV_PART_MAIN);		// 设置part main在默认状态下的背景颜色		
	lv_obj_set_style_bg_grad_color(panel_temp_value, lv_color_make(25, 28, 38), LV_PART_MAIN);	// 设置part main在默认状态下的背景渐变颜色
	lv_obj_set_style_bg_grad_dir(panel_temp_value, LV_GRAD_DIR_VER, LV_PART_MAIN);				// 设置part main在默认状态下的背景渐变方向
	lv_obj_set_style_border_color(panel_temp_value, lv_color_make(90, 100, 110), LV_PART_MAIN);	// 设置part main在默认状态下的边框宽度
	//lv_obj_set_style_arc_width(panel3, 2, LV_PART_MAIN);

	/* 第4层:以前面的组件为容器(parent),创建一个label组件,用来展示 */
	lv_obj_t * label_temp = lv_label_create(panel_temp_value);
	lv_label_set_text_fmt(label_temp, "%d°", 23);
	lv_obj_center(label_temp);

	lv_obj_set_style_text_font(label_temp, &lv_100ask_font_source_han_mono_extra_light_32, LV_PART_MAIN); 	// 设置label_temp在默认状态下的字体
	lv_obj_set_style_text_color(label_temp, lv_color_make(255, 255, 255), LV_PART_MAIN);					// 设置label_temp在默认状态下的字体颜色

	/* 事件处理回调函数,在控制台和label_temp上实时展示当前数值 */
	lv_obj_add_event_cb(arc_tmp, arc_event_cb, LV_EVENT_VALUE_CHANGED, label_temp);
	
}

你可能感兴趣的:(java,前端,服务器)