LVGL Layouts
LVGL 布局
Section titled “LVGL 布局”布局旨在自动定位组件,无需指定 x 和 y 坐标来定位每个组件。这是一种简化配置的极佳方式,允许你省略对齐选项。
布局配置选项应用于任何父组件或页面,影响子组件的外观。布局计算出的位置和大小会覆盖子组件的常规 x、y、width 和 height 设置。
查看食谱中的 弹性布局定位、网格布局定位 和 天气预报面板,这些示例展示了如何自动化组件定位,可能减少设备 YAML 配置的大小,并省去大量手动计算。
hidden、ignore_layout 和 floating 标志 可用于在布局计算中忽略组件。
- layout(可选,dict):
HORIZONTAL、VERTICAL、网格简写或描述布局配置的字典之一:- type(可选,string):
FLEX、GRID或NONE。默认为NONE。 - 根据所选类型,包含以下进一步选项。
- type(可选,string):
配置 layout: horizontal 是弹性布局的简写:
layout: type: flex flex_flow: row flex_align_main: space_evenly flex_align_track: center flex_align_cross: center此外,如果在容器上设置了 pad_all 选项(从而将填充应用于外部),相同的填充将应用于列之间,即 pad_column 将被设置。
配置 layout: vertical 是弹性布局的简写:
layout: type: flex flex_flow: column flex_align_main: space_evenly flex_align_track: center flex_align_cross: center与 horizontal 布局类似,在容器上使用 pad_all 也将把该填充应用于行之间。
LVGL 中的弹性布局是 CSS Flexbox 的子集实现。
它可以将其项排行为行或列(轨道),处理换行,调整项和轨道之间的间距,甚至处理扩展布局以让项填充剩余空间(同时考虑最小/最大宽度和高度)。
使用的术语:
- track(轨道):main(主)方向流动的行或列:项依次放置的方向。
- cross direction(交叉方向):垂直于主方向。
- wrap(换行):如果轨道中没有更多空间,则开始新轨道。
- gap(间距):行和列之间或轨道上项之间的空间。
- grow(增长):如果设置在某个项上,它将增长以填充轨道上的剩余空间。可用空间将根据项的增长值分配(值越大,空间越多)。它决定组件应占用多少可用空间。例如,如果轨道上的所有项的
grow都设为1,轨道中的空间将均等地分配给它们。如果其中一项的值为 2,该项将占用是其他项两倍的空間。
配置变量:
-
flex_flow(可选,string):选择子组件的排列方式:
ROW:将子组件排成一行,不换行。COLUMN:将子组件排成一列,不换行。ROW_WRAP:将子组件排成一行,带换行(默认)。COLUMN_WRAP:将子组件排成一列,带换行。ROW_REVERSE:将子组件排成一行,不换行,但顺序反转。COLUMN_REVERSE:将子组件排成一列,不换行,但顺序反转。ROW_WRAP_REVERSE:将子组件排成一行,带换行,但顺序反转。COLUMN_WRAP_REVERSE:将子组件排成一列,带换行,但顺序反转。
-
flex_align_main(可选,string):确定在主轴上如何分配轨道中的项。例如,使用
flex_flow: ROW_WRAP将项对齐到右侧(在 CSS 中称为 justify-content)。以下可用选项。 -
flex_align_cross(可选,string):确定在交叉轴上如何分配轨道中的项。例如,如果项的高度不同,则
flex_align_cross: end将每个项对齐到轨道底部(在 CSS 中称为 align-items)。以下可用选项。 -
flex_align_track(可选,string):确定如何分配轨道(在 CSS 中称为 align-content)。以下可用选项。
flex_align_main、flex_align_cross、flex_align_track的可用值:START:表示水平方向向左,垂直方向向上(默认)。END:表示水平方向向右,垂直方向向下。CENTER:简单地居中。SPACE_EVENLY:项的分布使任意两项之间(以及到边缘的距离)的间距相等。不适用于flex_align_track。SPACE_AROUND:项在轨道中均匀分布,周围有相等的空间。注意,视觉上间距并不相等,因为所有项两侧都有相等的空间。第一项将有一个单位的间距贴靠容器边缘,但与其下一个项之间有两个单位的间距,因为下一个项有自己的间距。不适用于flex_align_track。SPACE_BETWEEN:项在轨道中均匀分布:第一项在起始线上,最后一项在结束线上。不适用于flex_align_track。
flex_align_cross 选项还可以接受参数 STRETCH,这将使项填充交叉轴上的可用空间。这是通过设置每个项的默认高度或宽度为 100% 来实现的。项上明确的高度或宽度将覆盖此设置。
- pad_row(可选,int16):设置行之间的间距,以像素为单位。
- pad_column(可选,int16):设置列之间的间距,以像素为单位。
- flex_grow(可选,int16):可用于使一个或多个子组件填充轨道上的可用空间。当一个或多个子组件设置了
flex_grow时,可用空间将按比例分配给增长值。默认为0,即禁用增长。
# 弹性布局示例
- obj: layout: type: flex pad_row: 4 pad_column: 4px flex_align_main: center flex_align_cross: start flex_align_track: end widgets: - animimg: flex_grow: 1LVGL 中的网格布局是 CSS Grid 的子集实现。
它可以将其项排列为具有行或列(轨道)的二维”表格”。项可以跨越多个列或行。轨道的大小可以设置为像素、轨道上最大项的大小(CONTENT),或使用”自由单位”按比例分配自由空间。
使用的术语:
- tracks(轨道):行或列。
- gap(间距):行和列之间或轨道上项之间的空间。
- free unit (FR)(自由单位):轨道上可用空间的比例分配单位。它接受一个无单位的整数值作为比例。它决定组件应占用多少可用空间。例如,如果轨道上的所有项的
FR都设为1,轨道中的空间将均等地分配给它们。如果其中一项的值为 2,该项将占用是其他项两倍的空间。
单元格定位:
子组件可以使用 grid_cell_row_pos 和 grid_cell_column_pos 配置变量放置在网格上。
如果指定了其中任何一个,则两者都必须指定。如果两者都未指定,组件将以行优先顺序放置在第一个可用位置。
预留空间时会考虑行和列的跨越。
除非将 multiple_widgets_per_cell 选项设为 true,否则两个或更多组件不得被明确分配相同的行和列位置。
配置 layout: <rows>x<cols> 是网格布局的简写,指定行数和列数,所有行和列大小相等。例如,layout: 2x3 是以下配置的简写:
layout: type: grid grid_rows: [FR(1), FR(1)] grid_columns: [FR(1), FR(1), FR(1)] grid_cell_x_align: center grid_cell_y_align: center简写中可以省略任意一个维度;缺失的维度将从配置的组件数量中计算得出:
layout: <rows>x指定行数;列数计算为组件数除以行数(向上取整)。layout: x<cols>指定列数;行数计算为组件数除以列数(向上取整)。
例如,有五个组件时,layout: x3 和 layout: 2x 都将产生 2 行 3 列的网格。
如果没有组件,缺失的维度默认为 1。
配置变量(必须放在 layout 键下):
- grid_rows(可选):网格中的行,可以指定为像素值、
CONTENT或FR(n)(自由单位,其中n是比例整数值)的列表,或者指定为单个正整数,表示相同大小的FR(1)行数。如果指定了grid_columns则可以省略,此时行数从组件数量派生。 - grid_columns(可选):网格中的列,可以指定为像素值、
CONTENT或FR(n)(自由单位,其中n是比例整数值)的列表,或者指定为单个正整数,表示相同大小的FR(1)列数。如果指定了grid_rows则可以省略,此时列数从组件数量派生。 - grid_row_align(可选,string):如何对齐行。如果任何行大小使用
FR(n),则无效,因为任何自由空间都将分配给该行。以下可用选项。 - grid_column_align(可选,string):如何对齐列。如果任何列大小使用
FR(n),则无效,因为任何自由空间都将分配给该列。以下可用选项。 - pad_row(可选,int16):设置行之间的间距,以像素为单位。
- pad_column(可选,int16):设置列之间的间距,以像素为单位。
- multiple_widgets_per_cell(可选,bool):如果为
true,可以在同一个单元格中放置多个组件。默认为false。 - grid_cell_x_align(可选,string):单元格的
grid_cell_x_align默认值。如果使用简写布局,将默认为center。可以在单个组件上覆盖。 - grid_cell_y_align(可选,string):单元格的
grid_cell_y_align默认值。如果使用简写布局,将默认为center。可以在单个组件上覆盖。
必须指定 grid_rows 和 grid_columns 中的至少一个。行数和列数都必须大于零。
在网格布局中,放置在网格上的所有子组件都具有额外的配置选项:
- grid_cell_row_pos(可选,int16):组件的位置,即出现在第几行(从 0 开始计数)。
- grid_cell_column_pos(可选,int16):组件的位置,即出现在第几列(从 0 开始计数)。
- grid_cell_x_align(可选,string):如何水平对齐单元格内的组件。也可以通过样式属性应用。以下可用选项。
- grid_cell_y_align(可选,string):如何垂直对齐单元格内的组件。也可以通过样式属性应用。以下可用选项。
- grid_cell_row_span(可选,int16):组件跨越多少行。默认为
1。 - grid_cell_column_span(可选,int16):组件跨越多少列。默认为
1。
NOTE
这些 grid_cell_ 变量应用于网格布局内的单个组件(单元格)!
grid_column_align、grid_row_align、grid_cell_x_align、grid_cell_y_align 的可用值:
START:表示水平方向向左,垂直方向向上(默认)。END:表示水平方向向右,垂直方向向下。CENTER:简单地居中。STRETCH:将组件拉伸到单元格中相应的方向。不适用于grid_column_align、grid_row_align。SPACE_EVENLY:项的分布使任意两项之间(以及到边缘的距离)的间距相等。SPACE_AROUND:项在轨道中均匀分布,周围有相等的空间。注意,视觉上间距并不相等,因为所有项两侧都有相等的空间。第一项将有一个单位的间距贴靠容器边缘,但与其下一个项之间有两个单位的间距,因为下一个项有自己的间距。SPACE_BETWEEN:项在轨道中均匀分布:第一项在起始线上,最后一项在结束线上。
# 网格布局示例
- obj: layout: type: grid grid_row_align: end grid_rows: [ 100px, fr(1), content ] grid_columns: [ fr(1), fr(1) ] pad_row: 12px pad_column: 12px widgets: - image: src: image_id grid_cell_row_pos: 0 grid_cell_column_pos: 0 on_click: lvgl.page.next: - label: text: "row 0, column 1" grid_cell_row_pos: 0 grid_cell_column_pos: 1 - label: text: "row 2, column 0" grid_cell_row_pos: 2 grid_cell_column_pos: 0 - label: text: "row 1, column 0" - label: text: "row 1, column 1" - label: long_mode: wrap text: "row 2, col 1 (2/0 occupied)"
TIP
要可视化透明组件的真实计算大小,可以临时在其上设置 outline_width: 1。
运行时更新布局
Section titled “运行时更新布局”可以向 lvgl.update 和 lvgl.widget.update 操作提供 layout: 选项,以便在设备运行时更改容器的布局选项。例如,在显示方向改变时重新流式排列屏幕很有用。
仅可以通过这种方式更改布局选项。布局类型(FLEX/GRID)和网格结构(grid_rows/grid_columns)在组件创建时即固定,因为它们决定了哪些选项对子组件可用以及这些子组件占据哪些网格单元格。尝试在更新中设置它们是配置错误。可更新的选项有:
- 弹性布局:
flex_flow、flex_align_main、flex_align_cross、flex_align_track - 网格布局:
grid_column_align、grid_row_align - 两种布局均可:
pad_row、pad_column
只有实际指定的选项会更改;省略的选项保持当前值。
当应用于 lvgl.update 操作时,顶层 layout: 更新当前活动屏幕,而 top_layer: 或 bottom_layer: 下的 layout: 更新该显示层。
# 当显示方向改变时重新流式排列组件lvgl: on_landscape: - lvgl.widget.update: id: my_container layout: flex_flow: row on_portrait: - lvgl.widget.update: id: my_container layout: flex_flow: column # 更新活动屏幕本身的布局 - lvgl.update: layout: pad_row: 8px