# VerticalLayout

> 把子组件从上到下依次堆叠，每个都占满容器的宽度，是表单最常用的布局。

Source: https://crossfly.dev/zh/docs/ui/layouts/vertical-layout — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# VerticalLayout

将子组件**从上到下**堆叠（每个子组件一行），每个都占据**容器的宽度**（减去边距）。它是使用最多的布局——大多数屏幕的骨架。

> 🟢 · **包：** `dev.crossfly.ui.layout` · **继承自：** `Layout`

## 何时使用
- 单列屏幕：页眉 + 内容 + 页脚。
- 任何堆叠区块的列表。

## 何时不要使用
- 各项并排 → [HorizontalLayout](/docs/ui/layouts/horizontal-layout)。
- 标签/字段网格 → [GridLayout](/docs/ui/layouts/grid-layout)。

## `add(...)` — 签名与语义
```java
public VerticalLayout add(float altura, Component c)
```
参数 **`altura`** 控制该行：

| 值 | 含义 |
|---|---|
| `LAY_AUTO`（`0f`） | 组件的**自然高度**（`getAutoHeight()`）——随字体缩放 |
| `LAY_FILL`（`-1f`） | **填满剩余空间**（每个布局用**一**行 FILL） |
| `> 0`（例如 `0.25f`） | **容器高度的分数**（25%）——不是像素 |

## 构造函数
| 构造函数 | 说明 |
|---|---|
| `new VerticalLayout()` | 每一行水平**居中**对齐 |
| `new VerticalLayout(Position h, Position v)` | `h` = 各行的水平对齐方式（`START`/`CENTER`/`END`） |

## 完整示例（复制、粘贴并运行）
```java
package com.exemplo;

import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;

/** 可执行的主界面。将 launcher 指向此类（classname）并运行：gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      setLayout(new VerticalLayout(Position.START, Position.START));

      Component lista = new Component();          // 弹性内容（占位符）
      lista.setLayout(new VerticalLayout(Position.START, Position.START));
      for (int i = 1; i <= 5; i++)
         lista.add(LAY_AUTO, new Label("Produto " + i));

      add(LAY_AUTO, new Label("Produtos"));   // 头部——自然高度
      add(LAY_FILL, lista);                    // 内容——吸收全部剩余空间
      add(LAY_AUTO, new Button("Adicionar"));  // 底部——自然高度
   }
}
```

> 下面的片段只展示**核心部分**（放进 `onShow()` 里的内容）。要运行它们，请将其放入上面的 `MainWindow` 骨架中。

## 基本用法
```java
setLayout(new VerticalLayout(Position.START, Position.START));
add(LAY_AUTO, new Label("Produtos"));   // 头部——自然高度
add(LAY_FILL, lista);                    // 内容——吸收全部剩余空间
add(LAY_AUTO, new Button("Adicionar"));  // 底部——自然高度
```

## 排布方式
```
┌──────────────────────────┐
│ Label   (LAY_AUTO)        │  ← altura natural
├──────────────────────────┤
│                          │
│ lista   (LAY_FILL)       │  ← preenche o que sobrou
│                          │
├──────────────────────────┤
│ Button  (LAY_AUTO)        │  ← altura natural
└──────────────────────────┘
```

## 最佳实践
- **1 行 `LAY_FILL` + 其余为 `LAY_AUTO`** 是最稳健的排布方式（字体变大或键盘弹出时不会出问题）。
- 为各行留出间距：插入 `add(LAY_AUTO, Gap.ofFont(0.25f))` 作为间隔（该 `Gap` 算作一行半个字体高度）。

## 常见错误
- 给**所有**行都设定分数（全都用 `add(0.2f, …)`）——很脆弱；优先使用 auto + 1 个 fill。
- 以为 `add(0.7f, x)` 是**剩余空间**的 70%——它是容器**总高度**的 70%。
- 多于一行 `LAY_FILL`——只有最后一行生效。

## 另请参阅
- [HorizontalLayout](/docs/ui/layouts/horizontal-layout) · [GridLayout](/docs/ui/layouts/grid-layout) · [响应式设计](/docs/ui/layouts/responsiveness)
