11. 下拉列表部件
一、下拉列表部件
下拉列表部件常用于多选一的场景,其点击后可展开多个选项,用户可以从这些选项中选择一个,一旦选择好后,这些选项会自动收回。下拉列表部件由五个部分组成,按钮部分 由 ① 按钮的主体背景(LV_PART_MAIN
)和 ② 指示器(LV_PART_INDICATOR
),列表部分 由 ③ 当前选中的选项(LV_PART_SELECTED
)、④ 滚动条(LV_PART_SCROLLBAR
)和 ⑤ 列表主体背景(LV_PART_MAIN
)组成。
用户需要设置上述组成部分的样式,需要先将按钮或列表相关的部分获取回来。
LVGL 官方提供了一些与下拉列表部件相关 API。
lv_obj_t * lv_dropdown_create(lv_obj_t * parent); // 创建下拉列表
void lv_dropdown_set_text(lv_obj_t * obj, const char * txt); // 设置下拉列表按钮的文本(常显文本)
const char * lv_dropdown_get_text(lv_obj_t * obj); // 获取下拉列表按钮的文本
void lv_dropdown_set_options(lv_obj_t * obj, const char * options); // 动态方式添加选项
void lv_dropdown_set_options_static(lv_obj_t * obj, const char * options); // 静态方式添加选项
const char * lv_dropdown_get_options(const lv_obj_t * obj); // 获取下拉列表的选项
void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos); // 指定索引处添加单个选项
void lv_dropdown_clear_options(lv_obj_t * obj); // 清除所有选项
#define lv_dropdown_get_option_cnt lv_dropdown_get_option_count
uint32_t lv_dropdown_get_option_count(const lv_obj_t * obj); // 获取选项的总数
void lv_dropdown_set_selected(lv_obj_t * obj, uint32_t sel_opt); // 设置当前的选中项
uint32_t lv_dropdown_get_selected(const lv_obj_t * obj); // 获取当前选项的索引
void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size); // 获取当前选中项的文本
void lv_dropdown_set_selected_highlight(lv_obj_t * obj, bool en); // 设置当前选中的选项是否高亮
bool lv_dropdown_get_selected_highlight(lv_obj_t * obj); // 判断当前选中的选项是否高亮
void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir); // 设置展开方式
lv_dir_t lv_dropdown_get_dir(const lv_obj_t * obj); // 获取展开方向
void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol); // 设置图标
const char * lv_dropdown_get_symbol(lv_obj_t * obj); // 获取图标
lv_obj_t * lv_dropdown_get_list(lv_obj_t * obj); // 获取下拉列表,以设置样式或进行其它修改
void lv_dropdown_open(lv_obj_t * dropdown_obj); // 打开下拉列表
void lv_dropdown_close(lv_obj_t * obj); // 关闭下拉列表
我们可以通过 lv_dropdown_create()
函数 创建下拉列表。
/**
* @brief 创建下拉列表
*
* @param parent 指向父部件的指针
* @return lv_obj_t* 指向下拉列表部件的指针
*/
lv_obj_t * lv_dropdown_create(lv_obj_t * parent);
在创建完下拉列表部件后,我们可以通过 lv_dropdown_set_options()
函数 添加选项。
/**
* @brief 动态方式添加选项
*
* @param obj 指向下拉列表部件的指针
* @param options 选项相关的字符串数组,多个选项之间以\n分隔
*/
void lv_dropdown_set_options(lv_obj_t * obj, const char * options);
我们还可以通过 lv_dropdown_add_option()
在 指定索引处添加单个选项。
/**
* @brief 指定索引处添加单个选项
*
* @param obj 指向下拉列表部件的指针
* @param option 选项相关的字符串数组
* @param pos 要添加选项的的索引
*/
void lv_dropdown_add_option(lv_obj_t * obj, const char * option, uint32_t pos);
在添加完选项后,我们可以通过 lv_dropdown_set_selected()
函数 设置当前所选项。
/**
* @brief 设置当前的选中项
*
* @param obj 指向下拉列表部件的指针
* @param sel_opt 要设置的索引
*/
void lv_dropdown_set_selected(lv_obj_t * obj, uint32_t sel_opt);
然后,我们可以通过 lv_dropdown_get_selected()
函数 获取所选选项的索引。
/**
* @brief 获取当前选项的索引
*
* @param obj 指向下拉列表部件的指针
* @return uint32_t 当前选中项的索引
*/
uint32_t lv_dropdown_get_selected(const lv_obj_t * obj);
如果,我们想要 获取当前选中项的文本,可以通过 lv_dropdown_get_selected_str()
函数获取。
/**
* @brief 获取当前选中项的文本
*
* @param obj 指向下拉列表部件的指针
* @param buf 保存当前选中项的文本的缓冲数组
* @param buf_size 缓冲数据的大小
*/
void lv_dropdown_get_selected_str(const lv_obj_t * obj, char * buf, uint32_t buf_size);
在默认的情况下,当用户点击下拉列表后,其都是往下展开的,如果用户想 修改列表展开的方向,可以调用以下函数:
/**
* @brief 设置展开方式
*
* @param obj 指向下拉列表部件的指针
* @param dir 要设置的展开方式
*/
void lv_dropdown_set_dir(lv_obj_t * obj, lv_dir_t dir);
形参 dir
代表 列表的展开方向,用户可以选择上、下、左、右四个方向。
enum _lv_dir_t {
LV_DIR_NONE = 0x00,
LV_DIR_LEFT = (1 << 0),
LV_DIR_RIGHT = (1 << 1),
LV_DIR_TOP = (1 << 2),
LV_DIR_BOTTOM = (1 << 3),
LV_DIR_HOR = LV_DIR_LEFT | LV_DIR_RIGHT,
LV_DIR_VER = LV_DIR_TOP | LV_DIR_BOTTOM,
LV_DIR_ALL = LV_DIR_HOR | LV_DIR_VER,
};
下拉列表的图标箭头默认是向下的,如果用户修改了列表的展开方向,此时的箭头方向和展开方向就对应不上了。为了解决上述的问题,LVGL 提供了相关的图标设置函数:
/**
* @brief 设置图标
*
* @param obj 指向下拉列表部件的指针
* @param symbol 要设置的图标
*/
void lv_dropdown_set_symbol(lv_obj_t * obj, const void * symbol);
形参 symbol
为 要设置的图标。
二、实验例程
#include "lvgl.h"
#include "lv_port_disp_template.h"
#include "lv_port_indev_template.h"
lv_obj_t *label;
int main(void)
{
HAL_Init();
System_Clock_Init(8, 336, 2, 7);
Delay_Init(168);
SPI_Simulate_Init();
// SRAM_Init();
TIM_Base_Init(&g_tim6_handle, TIM6, 83, 999);
__HAL_TIM_CLEAR_IT(&g_tim6_handle, TIM_IT_UPDATE); // 清除更新中断标志位
HAL_TIM_Base_Start_IT(&g_tim6_handle); // 使能更新中断,并启动计数器
lv_init();
lv_port_disp_init();
lv_port_indev_init();
// 测试代码
label = lv_label_create(lv_scr_act()); // 创建标签部件
lv_obj_set_align(label, LV_ALIGN_TOP_MID); // 设置标签部件靠上居中对齐
lv_obj_set_style_text_font(label, &lv_font_montserrat_30, LV_PART_MAIN); // 设置标签部件的字体样式
lv_label_set_text(label, "dropDown list test"); // 设置标签部件的文本
lv_obj_t *dropDown_list = lv_dropdown_create(lv_scr_act()); // 创建下拉列表部件
lv_obj_center(dropDown_list); // 下拉列表部件居中对齐
lv_dropdown_set_options(dropDown_list, "Sakura\nMikoto\nShana"); // 设置下拉列表选项
lv_dropdown_add_option(dropDown_list, "Rimuru", 1); // 指定索引处添加单个选项
lv_dropdown_set_selected(dropDown_list, 1); // 设置当前的选中项
lv_dropdown_set_dir(dropDown_list, LV_DIR_RIGHT); // 设置展开方式
lv_dropdown_set_symbol(dropDown_list, LV_SYMBOL_RIGHT); // 设置图标
lv_obj_add_event_cb(dropDown_list, dorpDown_list_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
while (1)
{
lv_timer_handler();
Delay_ms(5);
}
return 0;
}
void dorpDown_list_event_cb(lv_event_t *e)
{
lv_event_code_t code = lv_event_get_code(e); // 获取事件的触发类型
lv_obj_t *target = lv_event_get_target(e); // 获取事件的触发源
char str[32];
uint32_t index = 0;
if (code == LV_EVENT_VALUE_CHANGED)
{
index = lv_dropdown_get_selected(target); // 获取选中的选项索引
lv_dropdown_get_selected_str(target, str, sizeof(str)); // 获取选中的选项字符串
lv_label_set_text_fmt(label, "select %s, index %ld", str, index);
}
}