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);
}
这段代码主要是介绍了,各种添加文字的方法,甚至有通过点击文字来进入回调事件的方法。,比较简单就不介绍了。
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);
}
lv_obj_t * btn = lv_btn_create(lv_scr_act())
:创建一个按钮对象,并将其父对象设置为活动屏幕对象。
lv_obj_set_style_bg_color(btn, lv_color_hex(0x1e1e1e), LV_PART_MAIN | LV_STATE_PRESSED)
:将按钮对象的背景色设置为灰色,并在按钮被按下时设置为按下状态。
lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE)
:为按钮对象添加LV_OBJ_FLAG_CHECKABLE
标志,使其具有可选中状态。
lv_obj_add_event_cb(btn, btn_toggle_event_cb, LV_EVENT_VALUE_CHANGED, NULL)
:为按钮对象添加LV_EVENT_VALUE_CHANGED
事件回调函数,即btn_toggle_event_cb
。当按钮对象的值发生变化时,该回调函数将被触发。在
btn_toggle_event_cb
回调函数中,通过lv_event_get_target(e)
获取触发事件的对象,通过lv_event_get_code(e)
获取当前对象触发的事件代码。在这个例子中,只处理LV_EVENT_VALUE_CHANGED
事件类型,在回调函数中打印出该事件类型的名称。
// 用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);
}
这份代码,主要是从只能由触摸屏手指点击来操作滑杆,按键等样式的基础上,增加了使用键盘和鼠标滚轮等方式来控制
按下键盘的ENTER可以按下按键,通过键盘的上下左右也可以控制滑杆的移动,鼠标滚轮则是可以上下滑动来选择你要控制的对象样式
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);
}
代码比较简单,API在之前也讲过,就不赘述了,主要现象也很简单
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:让对象居中,较为灵活
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
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); // 清除禁用状态,复选框可正常使用
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); // 设置按钮显示的字符
显示按钮字符:
lv_dropdown_set_text(dd, "Some text"); // 设置当选中选项之后展示的内容,如果没有这句,那么选中的是什么就展示什么
添加选项中的字体:
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); } } }
代码的注释写得很清楚
// 通过其他部件选择
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 事件 } }
该按钮做的主要是每按下一次,则选到下一个选项。
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);
更改点击后进度条的颜色:(原本是蓝色,改成了青色)
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);
设置进度条反向增加:
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
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);
只能通过旋钮来控制滑杆
这里主要讲一下一个实例的项目:(现象如下:)
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); }
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);
}