lvgl的flex布局铺满整个容器(弹性布局铺满整个容器)

前言

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布局官方文档说明