• LVGL自定义组件__页面指示器


    前言

    LVGL对硬件的要求非常低,使用其自带的组件能够搭建出精美的界面,动效也很棒。但是如过移植到Linux平台下,开发稍微复杂的应用项目,那些组件就远远不够用了。为此需要自己自定义一些组件,以方便实用。

    效果

    为此,尝试开发了一个页面指示器,先看效果:
    在这里插入图片描述

    代码

    Talk is cheap, show me your code.

    circles.h

    #include "lvgl.h"
    #define MAX_INDEX 10
    typedef struct circles_ {
        int max_index;
        int active_index;
        lv_style_t *active_style;
        lv_style_t *inactive_style;
        lv_obj_t *circle_list[MAX_INDEX];
        lv_obj_t *parent;
        int (*click_callback)(void);
    
        const char * name;
        void (*init)(void);
    } circles_t;
    
    typedef struct callback_user_data_{
        circles_t *circles;
        int index;
    }callback_user_data_t;
    
    // set the active index
    int lv_circles_set_active_index(circles_t *circles, int index);
    // draw the circles on the screen
    int lv_draw_circles(circles_t *circles);
    
    //demo function
    
    void custom_components_circles_demo();
    
    • 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

    circles.c

    #include "circles.h"
    
    // usage:
    // 1. define the callback function
    void test_cb(lv_event_t *e){
    
        printf("hello world\n");
    }
    
    
    // 2.init the circles like this: 
    void custom_components_circles_demo(){
        static lv_style_t inactive_style;
        lv_style_init(&inactive_style);
        lv_style_set_radius(&inactive_style,5);
        lv_style_set_size(&inactive_style, 10);
        lv_style_set_bg_color(&inactive_style,lv_palette_main(LV_PALETTE_GREY));
        lv_style_set_bg_opa(&inactive_style, 255);
        lv_style_set_text_opa(&inactive_style, 0);
    
        static lv_style_t active_style;
        lv_style_init(&active_style);
        lv_style_set_radius(&active_style,5);
        // lv_style_set_size(&active_style, 10);
        lv_style_set_width(&active_style, 20);
        lv_style_set_height(&active_style, 10);
        lv_style_set_bg_color(&active_style,lv_palette_main(LV_PALETTE_BLUE));
        lv_style_set_bg_opa(&active_style, 255);
        lv_style_set_text_opa(&active_style, 0);
    
        circles_t *circles;
        circles = (circles_t *)malloc(sizeof(circles_t));
        circles->active_style = &active_style;
        circles->inactive_style = &inactive_style;
    
        circles->max_index = 3;
        circles->active_index = 0;
        circles->name = "circles";
        circles->parent = lv_obj_create(lv_scr_act());
    
        lv_obj_set_size(circles->parent, 300, 75);
        lv_obj_set_flex_flow(circles->parent, LV_FLEX_FLOW_ROW);
        lv_obj_align(circles->parent,  LV_ALIGN_TOP_MID, 0, 5);
    
        circles->click_callback = test_cb;
        lv_draw_circles(circles);
    
    }
    
    int lv_circles_set_active_index(circles_t *circles, int index){
        if(index < 0 || index > circles->max_index) return -1;
        lv_obj_remove_style_all(circles->circle_list[circles->active_index]);
        lv_obj_remove_style_all(circles->circle_list[index]);
        lv_obj_add_style(circles->circle_list[circles->active_index], circles->inactive_style,0);
        lv_obj_add_style(circles->circle_list[index], circles->active_style,0);
    
        circles->active_index = index;
        return 0;
    }
    void lv_circles_event_cb(lv_event_t *e){
        callback_user_data_t *user_data = lv_event_get_user_data(e);
        lv_obj_t * btn = lv_event_get_target(e);
        lv_event_code_t code = lv_event_get_code(e);
        if(code == LV_EVENT_CLICKED){
            lv_circles_set_active_index(user_data->circles, user_data->index);
            if(user_data->circles->click_callback != NULL){
                user_data->circles->click_callback();
            }
        }
    }
    int lv_draw_circles(circles_t *circles){
        int i = 0;
        for(i =0;i<circles->max_index;i++){
            circles->circle_list[i] = lv_btn_create(circles->parent);
            lv_obj_remove_style_all(circles->circle_list[i]);
            callback_user_data_t *data = malloc(sizeof(callback_user_data_t));
            data->circles = circles;
            data->index = i;
            lv_obj_add_event_cb(circles->circle_list[i], lv_circles_event_cb, LV_EVENT_ALL, data);        
            if(i==circles->active_index){
                lv_obj_add_style(circles->circle_list[i], circles->active_style,0);
            }
            else{
                lv_obj_add_style(circles->circle_list[i], circles->inactive_style,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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88

    使用方法

    1. 项目根目录下,新建文件夹components,把上面的两个文件放进去
    2. 修改makefile
    INC  := -I./ui/simulator/inc/ -I./ -I./lvgl/ -I ./components
    
    • 1
    1. 要使用时引入头文件
    #include "circles.h"
    
    • 1
    1. 可以使用自带的Demo快速预览,具体使用方法可以参考Demo函数
    custom_components_circles_demo();
    
    • 1

    配置

    参考demo函数初始化配置即可:

    1. 建立点击回调函数,并注册到组件中,在指示器被点击后翻页使用
    2. 初始化active_style,inactive_style,设置自己需要的指示器样式
    3. 创建circles对象,初始化页面总个数和默认激活哪个页面
    4. 画到界面上

    总结

    由于刚刚上手lvgl,所以这个组件并没有完全基于lvgl中的基础对象lv_obj类型进行编写。感兴趣的同学可以参考官方组件的写法改写哦。

  • 相关阅读:
    模拟一个火车站售票小例子
    JavaWeb AJAX请求
    【嵌入式DIY实例-Nokia 5110显示LM35传感器数据
    matlab绘制雷达图
    CSDN竞赛第六期第二题(C++)
    Linux C/C++ 学习笔记(四):MYSQL安装与远程连接
    【近似最近邻搜索】在茫茫点集中,怎么找到你的邻居
    【python】flask中如何向https服务器传输信息
    Rust核心:【所有权】相关知识点
    Vue快速入门
  • 原文地址:https://blog.csdn.net/qq_18454025/article/details/128197513