# 弹性布局系统说明

本文将详细描述 LarkSDK 图形界面下推荐使用的布局模式:弹性布局。

弹性布局方案最初出现于 Web 端,在 2009 年第一次提出,一经放出就替代了落后的诸如表格布局等方案,随后就全面开花,大量投入应用。在 CSS 中称为弹性盒子布局(Flexbox) (opens new window),是一种较为先进的现代布局方式。

LarkSDK 吸收了弹性盒子布局的核心设计思想,目前已实现了弹性布局思路的核心功能,针对实际需求也进行了大量简化。在绝大多数情况下可以通过弹性布局完全替代锚点布局、流式布局、边框布局(东南西北中)等传统方案。

# 容器和元素

容器(Container)和元素(Element)在组件布局语境下是一对单纯的逻辑概念,本质上都是组件 LComponent。组件之间构成组件树,因此每个组件都属于一个父组件,也拥有零个或多个子组件。父组件就是容器,子组件就是元素。容器可以根据一定的算法来管理其内部所有子组件的定位与尺寸控制。该算法即称之为布局策略。弹性布局就是一种布局策略。

要应用弹性布局,需要构建布局对象 LFlexLayout。并调用容器组件的 setLayout() 接口。例如我们可以为顶层窗体的根组件应用弹性布局:

// 构建顶层窗体
LWindow w;

// 在顶层窗体的根组件应用弹性布局,轴向策略和离轴策略(后文讲述)均默认居中
w.rootComponent()->setLayout(LFlexLayout(LFlexLayout::Vertical));

TIP

弹性布局类 LFlexLayout 是抽象布局类 LLayout 的派生。后续会根据实际需求,通过抽象布局类实现更多的布局策略。

为容器应用布局之后,其内部元素就会遵循布局策略算法进行自动定位。

# 弹性布局基本概念

弹性布局是一种一维的布局策略,用于在容器中以按水平或竖直的方式排布元素。也就是说,弹性布局的主轴可以是水平方向或垂直方向。主轴的方向称为轴向。与主轴垂直的方向则称为离轴方向。

LarkSDK 弹性布局目前支持如下属性:

  • 主轴方向(水平方向、竖直方向)
  • 轴向布局策略(左侧对齐/顶端对齐、右侧对齐/底端对齐、居中)
  • 离轴布局策略(顶端对齐/左侧对齐、底端对齐/右侧对齐、居中、填满)
  • 容器内边距
  • 元素间距

后文会一一作出解释。

Fig 1

上图中,蓝色背景为一个容器,内部有四个标签组件。弹性布局默认设置主轴方向为水平、离轴方向为竖直。在主轴方向上,若所有元素的总尺寸不足以填满容器尺寸(例如主轴方向为横轴时,所有元素的总宽度小于容器宽度),我们认为容器在轴向拥有剩余空间。弹性布局策略本质上就是一种分配剩余空间的策略。

如果没有轴向剩余空间(所有元素的总轴向尺寸超出了容器的轴向尺寸),自然也将无法实现剩余空间分配,表现为元素恰好撑满或超出容器范围。在轴向上将跳过空间分配计算。

# 增长因子

每个元素都拥有一个称为增长因子(Growth)的非负值。这个值使得各元素在轴向上可以按比例通过增加尺寸以填满容器的剩余空间。该值默认为 0,表示元素的轴向尺寸不会增长,即不参与剩余空间分配。如果所有元素的增长因子均为 0,则所有元素在弹性布局的容器中,轴向尺寸均不会发生变化。

如果有一个或多个元素设置了非零的增长因子,则这些设置了增长因子的元素,将会根据各自增长因子的值所占增长因子综合的比例,来决定这些元素将按照何种比例分配容器的轴向剩余空间。例如,如果设置元素 C 的增长因子为 1,则表示元素 C 将吃掉全部的轴向剩余空间。

Fig 2

如果设置元素 C 的增长因子为 2,设置元素 D 的增长因子为 1,则轴向剩余空间将会被均分为 3 份,其中 2 份加在元素 C 的轴向尺寸上,1 份加在元素 D 的轴向尺寸上。直观感受就是元素 C 和 D 共同填满了剩余的轴向空间,但元素 C 占据的更多一些。

Fig 3

TIP

在 CSS 的 Flexbox 中存在压缩因子 flex-shrink 的概念,表示若元素的轴向尺寸综合超出了容器轴向空间,则按照比例对元素进行压缩。目前为简化设计起见 LarkSDK 的弹性布局暂不考虑元素的压缩,只考虑元素的增长。

目前通过 LComponent::setFlexGrowth() 接口设置元素的增长因子:

c.setFlexGrowth(2);
d.setFlexGrowth(1);

# 轴向布局策略

轴向布局策略决定了元素的轴向总尺寸不足以填充容器轴向尺寸时,元素对齐的位置。当主轴方向为水平方向时,轴向布局策略可以选择左侧对齐、右侧对齐或居中;当主轴水平方向为纵轴时,则可选择顶端对齐、右侧对齐或居中。

以主轴水平方向为例,下图依次为轴向左侧对齐、右侧对齐、居中:

Fig 4

TIP

显然的,轴向布局策略仅在所有元素均不设置增长因子时生效。

# 离轴布局策略

离轴布局策略决定了各元素如何填充离轴方向的剩余空间。当主轴方向为水平方向时,离轴布局策略可以选择顶端对齐、底端对齐、居中或填满;当主轴方向为纵轴时,则可选择左侧对齐、右侧对齐、居中或填满。

以主轴水平方向为例,下图依次为离轴顶端对齐、底端对齐、居中、填满:

Fig 5

# 容器内边距与元素间距

容器允许设置内边距。确保元素至少和容器边缘间隔一定距离。四个方向的内边距可以单独设置。容器也允许设置元素之间的间距。合理设置容器内编剧和元素间距可以使得布局效果更为美观。

下图为主轴横轴、元素 C 增长因子为 1 其余元素为 0、离轴方向设置为填满、容器内边距和元素间距均设置为 10 像素的效果:

Fig 6