lvgl 实现状态提示图标自动对齐补位显示
·
实现思路
- 通过数组索引表示状态图标or文字的位置
- 定时更新图标在数组的位置,然后再进行图标对齐,数组第n个元素向第n-1个元素对齐
具体实现
1、数据结构
struct state_prompts_pos {
lv_obj_t* prompts;
};
static struct state_prompts_pos _state_prompts_pos[5] = {
{.prompts = NULL},
{.prompts = NULL},
{.prompts = NULL},
{.prompts = NULL},
{.prompts = NULL},
};
#define STATE_PROMPTS_SIZE(_state_prompts) (sizeof(_state_prompts)/sizeof(_state_prompts[0]))
- lvgl用lv_obj_t表示元素,所以数组元素类型定义为lv_obj_t
- 数组的每一位表示一个状态。
2、向数组插入状态图标
static void state_prompts_set_prompts(lv_obj_t* prompts)
{
/* There has been a prompts */
for (char i = 0; i < STATE_PROMPTS_SIZE(_state_prompts_pos); i++)
{
if (_state_prompts_pos[i].prompts == prompts)
{
return;
}
}
for (char i = 0; i < STATE_PROMPTS_SIZE(_state_prompts_pos); i++)
{
if (_state_prompts_pos[i].prompts == NULL) /* find a free place */
{
_state_prompts_pos[i].prompts = prompts;
lv_obj_set_hidden(prompts, false);
//printf("set %d\r\n", i);
break;
}
}
}
- 需要保持obj在数组中的唯一性,插入的obj前是否已经在数组中
lv_obj_set_hidden(prompts, false)
,图标已经提前创建好,所以直接取消隐藏显示出来
3、从数组中删除obj
static void state_prompts_reset_prompts(lv_obj_t* prompts)
{
for (char i = 0; i < STATE_PROMPTS_SIZE(_state_prompts_pos); i++)
{
if (_state_prompts_pos[i].prompts == prompts)
{
_state_prompts_pos[i].prompts = NULL;
lv_obj_set_hidden(prompts, true);
//printf("reset %d\r\n", i);
break;
}
}
}
if (_state_prompts_pos[i].prompts == prompts)
在数据找到了要删除的objlv_obj_set_hidden(prompts, true);
,将图标隐藏,不显示_state_prompts_pos[i].prompts = NULL
;,将当前数组元素指针置NULL表示当前位置没有图标
4、更新状态图标位置
static void state_prompts_align_not_0(lv_obj_t* obj, lv_obj_t *base, lv_coord_t x, lv_coord_t y)
{
lv_obj_align(obj, base, LV_ALIGN_OUT_LEFT_MID, x, y);
}
void lv_update_state_prompts_pos_change(void)
{
for (char i = 0; i < (STATE_PROMPTS_SIZE(_state_prompts_pos)); i++)
{
if (_state_prompts_pos[i].prompts == NULL) /* if current obj is NULL */
{
char y = 0;
for (y = i; y < STATE_PROMPTS_SIZE(_state_prompts_pos)-1; y++)
{
if (_state_prompts_pos[y].prompts) break;
}
_state_prompts_pos[i].prompts = _state_prompts_pos[y].prompts;
_state_prompts_pos[y].prompts = NULL;
}
}
if (_state_prompts_pos[0].prompts)
{
lv_obj_t* par = lv_scr_act();
lv_obj_align(_state_prompts_pos[0].prompts, par, LV_ALIGN_IN_TOP_RIGHT, -10, 30);
}
for (char i = 1; i < STATE_PROMPTS_SIZE(_state_prompts_pos); i++)
{
if (_state_prompts_pos[i].prompts == NULL) continue;
state_prompts_align_not_0(_state_prompts_pos[i].prompts, _state_prompts_pos[i-1].prompts, -10, 0);
}
}
- 先更新数组元素,在进行对齐;当数组当前元素为NULL,就向上查找不为NULL的,将其移到到当前位置,然后将从图标的位置置NULL
if (_state_prompts_pos[0].prompts)
,特殊处理第1个图标位置state_prompts_align_not_0(_state_prompts_pos[i].prompts, _state_prompts_pos[i-1].prompts, -10, 0);
其他图标向前一个图标对齐
5、使用
- 创建1个定时lvgl task,在task回调函数中调用
lv_update_state_prompts_pos_change
- 在状态的条件触发时,调用
state_prompts_set_prompts
插入obj - 在状态条件取消时,调用
state_prompts_reset_prompts
删除obj
实现效果
更多推荐
已为社区贡献4条内容
所有评论(0)