Flex(弹性布局)![](https://img-blog.csdnimg.cn/direct/a65d39919fd346489f5357448dc4475a.png)
Overview(概述)
Flexbox(或简称 Flex)是 CSS Flexbox 的一个子集。
它可以将项目排列成行或列(轨道),处理环绕,调整项目和轨道之间的间距,处理 grow 以使项目填充剩余空间的最小/最大宽度和高度。
要使对象 flex 容器调用 lv_obj_set_layout(obj, LV_LAYOUT_FLEX)。
请注意,LVGL 的 flex 布局功能需要通过 lv_conf.h 中的 LV_USE_FLEX 全局启用。
Terms(约定)
(tracks) 轨道:行或列(main direction) 主要方向:行或列,物品放置的方向
(cross direction) 横向:垂直于主方向
(wrap) 环绕:如果曲目中没有更多空间,则开始新曲目
(grow) 增长:如果设置在一个项目上,它将增长以填充轨道上的剩余空间。 可用空间将根据其增长值分配给各个项目(值越大意味着空间越大)
(gap) 间隙:行和列或轨道上的项目之间的空间
使用以下功能,您可以在任何父级上设置 Flex 布局。
Flex flow 位置浮动
lv_obj_set_flex_flow(obj, flex_flow)
flex_flow 的可能值是:
LV_FLEX_FLOW_ROW | 将子元素排成一排而不包裹 |
LV_FLEX_FLOW_COLUMN | 将子项放在一列中而不换行 |
LV_FLEX_FLOW_ROW_WRAP | 将孩子排成一排并包裹起来 |
LV_FLEX_FLOW_COLUMN_WRAP | 将子元素放置在带有环绕的列中 |
LV_FLEX_FLOW_ROW_REVERSE | 将子元素排成一行而不换行,但顺序相反 |
LV_FLEX_FLOW_COLUMN_REVERSE | 将子项放在一列中,不换行,但顺序相反 |
LV_FLEX_FLOW_ROW_WRAP_REVERSE | 将子元素排成一行而不换行,但顺序相反 |
LV_FLEX_FLOW_COLUMN_WRAP_REVERSE | 将子项放在一列中,不换行,但顺序相反 |
Flex align 位置对齐
要管理位置,请使用
lv_obj_set_flex_align(obj, main_place, cross_place, track_cross_place)
main_place
确定如何在主轴上的轨道中分布项目
例如。 将“LV_FLEX_FLOW_ROW_WRAP”上的项目向右刷新。 (它在 CSS 中称为 justify-content)
cross_place
确定如何在横轴上的轨道中分布项目
例如。 如果项目具有不同的高度,则将它们放置在轨道的底部。 (在 CSS 中称为 align-items)
track_cross_place 确定如何分配轨道(在 CSS 中称为 align-content)
可能的值为:
- LV_FLEX_ALIGN_START | 表示在水平方向和垂直方向的顶部左侧。 (默认)
- LV_FLEX_ALIGN_END | 表示水平和底部垂直
- LV_FLEX_ALIGN_CENTER | 只是居中
- LV_FLEX_ALIGN_SPACE_EVENLY | 项目是分布的,因此任意两个项目之间的间距(以及到边缘的空间)是相等的。 不适用于track_cross_place。
- LV_FLEX_ALIGN_SPACE_AROUND | 项目均匀分布在轨道中,它们周围的空间相等。 请注意,视觉上的空间并不相等,因为所有项目的两侧都有相等的空间。 第一个项目将与容器边缘有一个单位的空间,但下一个项目之间有两个单位的空间,因为下一个项目有自己的适用间距。 不适用于track_cross_place。
- LV_FLEX_ALIGN_SPACE_BETWEEN |项目均匀分布在轨道中:第一个项目在开始线上,最后一个项目在结束线上。 不适用于track_cross_place。
Flex grow
Flex Growth 可用于让一个或多个孩子填充轨道上的可用空间。 如果有更多的孩子成长,可用空间将与成长值成比例地分配。 例如,让我们有 400 像素的剩余空间和 4 个增长的对象:
A 增长 = 1
B 增长 = 1
C 增长 = 2
A 和 B 的大小为 100 px,而 C 的大小为 200 px。
可以使用 lv_obj_set_flex_grow(child, value) 在子节点上设置 Flex 增长。 value 需要 > 1 或 0 禁用在孩子身上生长。
Style interface(样式接口)
所有与 Flex 相关的值都是底层的样式属性,您可以像使用任何其他样式属性一样使用它们。 存在以下与 flex 相关的样式属性:
- FLEX_FLOW
- FLEX_MAIN_PLACE
- FLEX_CROSS_PLACE
- FLEX_TRACK_PLACE
- FLEX_GROW
Other features(其它功能)
如果容器的基本方向设置为 LV_BASE_DIR_RTL,LV_FLEX_ALIGN_START 和 LV_FLEX_ALIGN_END 的含义在 ROW 布局上交换。 START 表示正确。
ROW 布局上的项目和 COLUMN 布局的轨道将从右到左放置。
New track(新轨道)
您可以使用 lv_obj_add_flag(child, LV_OBJ_FLAG_FLEX_IN_NEW_TRACK) 强制 Flex 将项目放入新行。
重点理解:
示例代码:Flex布局示例
示例说明:
该示例代码演示了如何使用Flex布局创建简单的Flex布局。
该示例创建了一个包含两个按键容器的屏幕对象,并在其中放置了10个按钮对象。
其中,第一个按键容器包含10个按钮对象,排列方式为横向排列;第二个按键容器包含10个按钮对象,排列方式为纵向排列。
#include "../../lv_examples.h"
#if LV_USE_FLEX && LV_BUILD_EXAMPLES
/* 示例代码:Flex布局示例1
* 该示例代码演示了如何使用Flex布局创建简单的Flex布局。
* 该示例创建了一个包含两个按键容器的屏幕对象,并在其中放置了10个按钮对象。
* 其中,第一个按键容器包含10个按钮对象,排列方式为横向排列;第二个按键容器包含10个按钮对象,排列方式为纵向排列。
*/
void lv_my_example_flex_1(void)
{
//创建一个新的容器对象
lv_obj_t * cont_row = lv_obj_create(lv_scr_act());
//设置其大小为300x75
lv_obj_set_size(cont_row, 300, 75);
//将该容器对象与父对象的顶部中间对齐,偏移坐标为(0, 5)
lv_obj_align(cont_row, LV_ALIGN_TOP_MID, 0, 5);
//设置该容器对象的布局方式为横向排列
lv_obj_set_flex_flow(cont_row, LV_FLEX_FLOW_ROW);
// 创建一个新的容器对象cont_col,该对象将放置在屏幕活动对象上
lv_obj_t * cont_col = lv_obj_create(lv_scr_act());
// 设置cont_col容器对象的尺寸为200x150
lv_obj_set_size(cont_col, 200, 150);
// 将cont_col容器对象与cont_row对象对齐,位置在cont_row对象的下方中间,并在垂直方向上偏移5个像素
lv_obj_align_to(cont_col, cont_row, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);
/*
* 设置cont_col容器对象的排列方式为纵向排列
*/
lv_obj_set_flex_flow(cont_col, LV_FLEX_FLOW_COLUMN);
uint32_t i;
for(i = 0; i < 10; i++) {
lv_obj_t * obj;
lv_obj_t * label;
// 在水平容器cont_row中创建按钮对象
obj = lv_btn_create(cont_row);
// 设置按钮对象的尺寸
lv_obj_set_size(obj, 100, LV_PCT(100));
// 在按钮对象上创建标签对象
label = lv_label_create(obj);
// 格式化标签中的文本内容
lv_label_set_text_fmt(label, "Item: %u", i);
// 居中显示标签对象
lv_obj_center(label);
// 在垂直容器cont_col中创建按钮对象
obj = lv_btn_create(cont_col);
// 设置按钮对象的尺寸
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
// 在按钮对象上创建标签对象
label = lv_label_create(obj);
// 格式化标签中的文本内容
lv_label_set_text_fmt(label, "Item: %"LV_PRIu32, i);
// 居中显示标签对象
lv_obj_center(label);
}
}
#endif
效果图: