• 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]))
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 需要保持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;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • if (_state_prompts_pos[i].prompts == prompts) 在数据找到了要删除的obj
    • lv_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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 先更新数组元素,在进行对齐;当数组当前元素为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

    实现效果

    在这里插入图片描述

  • 相关阅读:
    模糊神经网络算法matlab,模糊神经网络算法原理
    pyqtgraph只使用image view进行热图的可视化展示 (一个脚本)创建一个窗口
    Hadoop3 - MapReduce ORC 列式存储
    2022IDEA的下载、安装、配置与使用
    VRTK4 代码 取消/禁用 抓取
    python容器之列表(list)
    Mybatis 缓存原理
    Linux启动elasticsearch,提示权限不够
    LeetCode - 解题笔记 - 187 - Repeated DNA Sequences
    考研数据结构与算法(五)数组
  • 原文地址:https://blog.csdn.net/qq_36413982/article/details/126146283