前言
Flex 布局,是一种可以简便、完整、响应式地实现各种页面布局,她是CSS的一个重点应用。lvgl从v8版本^1开始支持类似 CSS 的 Flexbox 和 Grid 布局。^2
在使用 flex布局,我们可以非常方便的实现各种布局,但是也会遇到各种小问题,比如我们需要将铺满整个容器时会比较麻烦,因为官网的文档[^3]并没有说明怎么铺满整个容器,下面请看看我是怎么解决的吧。
未铺满的状态(默认样式)
我设置的屏幕大小是 1024*600,在中间创建了一个对象,这个对象中的布局使用 Flex 布局,默认创建出来的样式是有一定的预留空间的:
下面是上图的实现代码:
#define CONT_HOR_RES (700)
#define CONT_VER_RES (350)
#define OBJ_COUNT_HOR (6)
#define OBJ_COUNT_VER (4)
#define OBJ_COUNT (OBJ_COUNT_HOR * OBJ_COUNT_VER)
void lv_100ask_demo_memory(void)
{
static lv_style_t cont_style; // 容器的样式
static lv_style_t obj_style; // 容器中的对象的样式
/* 设置容器的样式 */
lv_style_init(&cont_style);
lv_style_set_bg_opa(&cont_style, 0);
lv_style_set_radius(&cont_style, 0);
/* 容器中的对象的样式 */
lv_style_init(&obj_style);
lv_style_set_radius(&obj_style, 0);
lv_style_set_border_width(&obj_style, 1);
/* 使用 flex 创建容器 */
lv_obj_t * cont = lv_obj_create(lv_scr_act());
lv_obj_set_style_base_dir(cont, LV_BASE_DIR_LTR, 0);
lv_obj_set_style_pad_row(cont, 0, 0);
lv_obj_set_style_pad_column(cont, 0, 0);
lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_add_style(cont, &cont_style, 0);
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);
uint32_t i;
for(i = 1; i <= OBJ_COUNT; i++) {
lv_obj_t * obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_HOR_RES / OBJ_COUNT_HOR, LV_VER_RES / OBJ_COUNT_VER);
lv_obj_add_style(obj, &obj_style, 0);
lv_obj_t * label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d", i);
lv_obj_center(label);
}
}
改进:实现铺满
上面的代码中,其实所说的 Flex 容器就是一个普通的对象,我们在创建这个对象之后再将它的布局类型设置为 Flex 布局而已,实现起来非常简单。
要实现铺满整个,我们只要在样式上做修改即可,指定样式属性:
lv_style_set_pad_all
指定之后我们就可以铺满整个容器,不会再有默认的预留空间。
实现效果:
基于上面的代码,添加一行代码即可:
#define CONT_HOR_RES (700)
#define CONT_VER_RES (350)
#define OBJ_COUNT_HOR (6)
#define OBJ_COUNT_VER (4)
#define OBJ_COUNT (OBJ_COUNT_HOR * OBJ_COUNT_VER)
void lv_100ask_demo_memory(void)
{
static lv_style_t cont_style; // 容器的样式
static lv_style_t obj_style; // 容器中的对象的样式
/* 设置容器的样式 */
lv_style_init(&cont_style);
lv_style_set_bg_opa(&cont_style, 0);
lv_style_set_radius(&cont_style, 0);
lv_style_set_pad_all(&cont_style, 0); // 铺满(新添加的一行代码)
/* 容器中的对象的样式 */
lv_style_init(&obj_style);
lv_style_set_radius(&obj_style, 0);
lv_style_set_border_width(&obj_style, 1);
/* 使用 flex 创建容器 */
lv_obj_t * cont = lv_obj_create(lv_scr_act());
lv_obj_set_style_base_dir(cont, LV_BASE_DIR_LTR, 0);
lv_obj_set_style_pad_row(cont, 0, 0);
lv_obj_set_style_pad_column(cont, 0, 0);
lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
lv_obj_align(cont, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_add_style(cont, &cont_style, 0);
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_ROW_WRAP);
uint32_t i;
for(i = 1; i <= OBJ_COUNT; i++) {
lv_obj_t * obj = lv_obj_create(cont);
lv_obj_set_size(obj, LV_HOR_RES / OBJ_COUNT_HOR, LV_VER_RES / OBJ_COUNT_VER);
lv_obj_add_style(obj, &obj_style, 0);
lv_obj_t * label = lv_label_create(obj);
lv_label_set_text_fmt(label, "%d", i);
lv_obj_center(label);
}
}
[^3]:LVGL Flex布局官方文档说明