目录
1. 构造矩阵
2. Parts
2.1 LV_PART_MAIN
2.2 LV_PART_ITEMS
3. 样式
3.1 按钮大小
3.2 间距
3.3 控制按钮
3.4 控制map
3.5 Check唯一性
4. 事件
4.1 LV_EVENT_VALUE_CHANGED
4.2 LV_EVENT_LONG_PRESSED
4.3 LV_EVENT_DRAW_PART_BEGIN
按钮矩阵是多个按钮的组合,例如直接绘制一个九宫格按键。按钮矩阵的按钮是实时绘制的,所以占用的内存会比较小。通过lv_btnmatrix_create函数创建按钮矩阵对象。
static lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());
1. 构造矩阵
通过一个称为map的描述符字符串数组来实现,每个字符串代表一个按钮,然后通过lv_btnmatrix_set_map设置这个map。
static lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());
static const char* btnMap[] = {
",", "ABC", "DEF", "\n",
"GHI", "JKL", "MNO", "\n",
"PQRS", "TUV", "WXYX", ""
};
lv_btnmatrix_set_map(btnM, btnMap);
lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);
map数组通过回车符换行,通过0表示结束,和字符串的定义一致。
2. Parts
按钮矩阵有2个Parts:LV_PART_MAIN和LV_PART_ITEMS。
2.1 LV_PART_MAIN
对应
按钮矩阵的背景。
lv_obj_set_style_bg_color(btnM, lv_color_make(252, 144, 181), LV_PART_MAIN);
2.2 LV_PART_ITEMS
对应
按钮矩阵的按钮。
lv_obj_set_style_bg_color(btnM, lv_color_make(252, 144, 181), LV_PART_ITEMS);
3. 样式
3.1 按钮大小
通过lv_btnmatrix_set_btn_width函数设置按钮大小。
void lv_btnmatrix_set_btn_width(lv_obj_t * obj, uint16_t btn_id, uint8_t width)
参数btn_id表示需要修改哪个按钮的宽度。
参数width和之前的宽度含义不同,不是以像素为单位,表示倍数的关系,有效值是1-7,设置为0时也是和1的设定一样。
lv_btnmatrix_set_btn_width(btnM, 0, 1);
lv_btnmatrix_set_btn_width(btnM, 3, 2);
对比上面2个设定(宽度为1和2的情况):
id为0和id为3的按钮被设置,可以看到id为0的按钮宽度还是1个单位宽度,而id为3的按钮宽度变为2个单位。注意这个单位宽度是当前x轴上平均宽度,比如上图第二行,总宽度是1,3个按钮分别的宽度是2/1/1,所以总宽度单位是4,1个单位宽度是25%,3个按钮分别占据50%,25%,25%。
3.2 间距
通过lv_obj_set_style_pad_row和lv_obj_set_style_pad_column可以调整按钮之间的间距。
void lv_obj_set_style_pad_row(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
void lv_obj_set_style_pad_column(struct _lv_obj_t * obj, lv_coord_t value, lv_style_selector_t selector)
lv_obj_set_style_pad_row(btnM, 2, LV_PART_MAIN);
lv_obj_set_style_pad_column(btnM, 2, LV_PART_MAIN);
另外可以通过lv_obj_set_style_pad_top,lv_obj_set_style_pad_bottom,lv_obj_set_style_pad_left和lv_obj_set_style_pad_right调整按钮和边界的距离。
3.3 控制按钮
通过lv_btnmatrix_set_btn_ctrl设置按钮的控制形态,通过lv_btnmatrix_clear_btn_ctrl清除。
void lv_btnmatrix_set_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl)
void lv_btnmatrix_clear_btn_ctrl(lv_obj_t * obj, uint16_t btn_id, lv_btnmatrix_ctrl_t ctrl)
通过lv_btnmatrix_set_btn_ctrl_all和lv_btnmatrix_clear_btn_ctrl_all设置所有按钮的控制形态。
控制形态的枚举,可以通过OR的方式多个控制
enum {
_LV_BTNMATRIX_WIDTH = 0x0007, /**< Reserved to stire the size units*/
LV_BTNMATRIX_CTRL_HIDDEN = 0x0008, /**< Button hidden*/
LV_BTNMATRIX_CTRL_NO_REPEAT = 0x0010, /**< Do not repeat press this button.*/
LV_BTNMATRIX_CTRL_DISABLED = 0x0020, /**< Disable this button.*/
LV_BTNMATRIX_CTRL_CHECKABLE = 0x0040, /**< The button can be toggled.*/
LV_BTNMATRIX_CTRL_CHECKED = 0x0080, /**< Button is currently toggled (e.g. checked).*/
LV_BTNMATRIX_CTRL_CLICK_TRIG = 0x0100, /**< 1: Send LV_EVENT_VALUE_CHANGE on CLICK, 0: Send LV_EVENT_VALUE_CHANGE on PRESS*/
LV_BTNMATRIX_CTRL_POPOVER = 0x0200, /**< Show a popover when pressing this key*/
LV_BTNMATRIX_CTRL_RECOLOR = 0x1000, /**< Enable text recoloring with `#color`*/
_LV_BTNMATRIX_CTRL_RESERVED = 0x2000, /**< Reserved for later use*/
LV_BTNMATRIX_CTRL_CUSTOM_1 = 0x4000, /**< Custom free to use flag*/
LV_BTNMATRIX_CTRL_CUSTOM_2 = 0x8000, /**< Custom free to use flag*/
};
LV_BTNMATRIX_CTRL_HIDDEN: 隐藏按钮。
LV_BTNMATRIX_CTRL_NO_REPEAT: 显示无区别,当长按时不重复按键事件。
LV_BTNMATRIX_CTRL_DISABLED:禁止按钮。蓝色圈不见了,点击不能选中。
LV_BTNMATRIX_CTRL_CHECKABLE: Check型按钮。
LV_BTNMATRIX_CTRL_CHECKED:按钮为选中状态,原则上需要和LV_BTNMATRIX_CTRL_CHECKABLE一起使用。
LV_BTNMATRIX_CTRL_CLICK_TRIG:和显示无关,表示按钮点击时在事件LV_EVENT_VALUE_CHANGE中发送1,按下时发送0.
LV_BTNMATRIX_CTRL_POPOVER:按键时弹出窗口。
LV_BTNMATRIX_CTRL_RECOLOR:启用文本可以通过‘#颜色’更改颜色。例如:
static lv_obj_t *btnM = lv_btnmatrix_create(lv_scr_act());
static const char* btnMap[] = {
",", "ABC", "DEF", "\n",
"#FF0000 GHI", "JKL", "MNO", "\n",
"#FF0000 PQRS", "TUV", "WXYX", ""
};
lv_btnmatrix_set_map(btnM, btnMap);
lv_btnmatrix_set_btn_ctrl(btnM, 3, LV_BTNMATRIX_CTRL_RECOLOR);
lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);
map中2个按钮写入了颜色的关键字,但是只启用了按钮3为改颜色。
3.4 控制map
和创建矩阵的map类似,设置控制属性时可以通过一个map直接设置所有的按钮。
static const char* btnMap[] = {
",", "ABC", "DEF", "\n",
"#FF0000 GHI", "JKL", "MNO", "\n",
"PQRS", "TUV", "WXYX", ""
};
static const lv_btnmatrix_ctrl_t ctrlMap[] =
{
1 | LV_BTNMATRIX_CTRL_CHECKABLE, 1, 1,
2 | LV_BTNMATRIX_CTRL_RECOLOR, 1, 1,
1, 1, 1 | LV_BTNMATRIX_CTRL_POPOVER
};
lv_btnmatrix_set_map(btnM, btnMap);
lv_btnmatrix_set_ctrl_map(btnM, ctrlMap);
//lv_btnmatrix_set_btn_ctrl(btnM, 3, LV_BTNMATRIX_CTRL_RECOLOR);
lv_obj_align(btnM, LV_ALIGN_CENTER, 0, 0);
3.5 Check唯一性
通过lv_btnmatrix_set_one_checked将矩阵中的按钮具有Check唯一性。
lv_btnmatrix_set_btn_ctrl_all(btnM, 1 | LV_BTNMATRIX_CTRL_CHECKABLE);
lv_btnmatrix_set_one_checked(btnM, true);
4. 事件
可以通过lv_btnmatrix_get_selected_btn获取事件对应的按钮ID,通过lv_btnmatrix_get_btn_text获取按钮的字符串。
在代码中添加事件回调函数
static void event_handler(lv_event_t* e)
{
}
lv_obj_add_event_cb(btnM, event_handler, LV_EVENT_ALL, NULL);
4.1 LV_EVENT_VALUE_CHANGED
static void 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)
{
uint32_t id = lv_btnmatrix_get_selected_btn(obj);
const char* txt = lv_btnmatrix_get_btn_text(obj, id);
LV_LOG_USER("%s was pressed\n", txt);
}
}
4.2 LV_EVENT_LONG_PRESSED
增加Label显示信息。
static void 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_LONG_PRESSED)
{
uint32_t id = lv_btnmatrix_get_selected_btn(obj);
lv_label_set_text_fmt(label1, "Long Pressed ID:%d", id);
}
}
4.3 LV_EVENT_DRAW_PART_BEGIN
这个事件常用于重绘,表示一个局部绘制的开始。
static void 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_DRAW_PART_BEGIN)
{
lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
if (dsc->class_p == &lv_btnmatrix_class && dsc->type == LV_BTNMATRIX_DRAW_PART_BTN)
{
if (dsc->id == 1)
{
if (lv_btnmatrix_get_selected_btn(obj) == dsc->id)
dsc->rect_dsc->bg_color = lv_palette_darken(LV_PALETTE_BLUE, 3);
else
dsc->rect_dsc->bg_color = lv_palette_main(LV_PALETTE_BLUE);
}
}
}
}
将第二个按钮的背景色改为蓝色。
还有一个LV_EVENT_DRAW_PART_END的事件,这个事件是刷新完按钮才响应的,可以用于在按钮上添加图片。