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 functionvoid custom_components_circles_demo();
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;imax_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);}}
}
components
,把上面的两个文件放进去makefile
:INC := -I./ui/simulator/inc/ -I./ -I./lvgl/ -I ./components
#include "circles.h"
custom_components_circles_demo();
参考demo函数初始化配置即可:
active_style,inactive_style
,设置自己需要的指示器样式circles
对象,初始化页面总个数和默认激活哪个页面由于刚刚上手lvgl,所以这个组件并没有完全基于lvgl中的基础对象lv_obj
类型进行编写。感兴趣的同学可以参考官方组件的写法改写哦。