# 布局

> 六种布局、add(LAY_AUTO/LAY_FILL/分数)以及为真实界面嵌套布局的技巧。

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

# 4. 布局

> **你将学到:** CrossFly 如何定位,以及**嵌套布局**以搭建真实界面的技巧。**前置条件:** [组件化思维](/docs/learn/thinking-in-components)。

## 完整示例(复制、粘贴、运行)
列表界面的最终结构,通过**嵌套布局**:header 用 `HorizontalLayout`(自动高度),内容用 `LAY_FILL` 弹性伸缩,页脚自动 —— 全部放在一个 `VerticalLayout` 里。可直接编译运行。
```java
package com.exemplo;

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

public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout(Position.START, Position.START));

      // header：HorizontalLayout，自然高度 (LAY_AUTO)
      Component header = new Component();
      header.setLayout(new HorizontalLayout(Position.START, Position.CENTER));
      header.add(LAY_AUTO, new Button(new MaterialIcon("")));   // 图标
      header.add(LAY_FILL, new Label("Minhas tarefas"));         // 标题吸收宽度
      add(LAY_AUTO, header);

      // 内容：“弹性”部分 — 吸收剩余高度
      Component conteudo = new Component();
      conteudo.setLayout(new VerticalLayout());
      conteudo.add(LAY_AUTO, new Label("Item 1"));
      conteudo.add(LAY_AUTO, new Label("Item 2"));
      conteudo.add(LAY_AUTO, new Label("Item 3"));
      add(LAY_FILL, conteudo);

      // 页脚：自然高度
      add(LAY_AUTO, new Button("Adicionar"));
   }
}
```
> 下面的片段只展示**核心部分**(放在 `onShow()` 里的内容)。要运行,请把它们放进上面的 `MainWindow` 骨架里。

## 六种布局
| 布局 | 用于 |
|---|---|
| `VerticalLayout` / `HorizontalLayout` | 向下堆叠 ↓ / 并排 → |
| `GridLayout` | 按分数的网格(先宽度,再组件) |
| `RelativeLayout` | 将一个组件锚定到另一个 |
| `EvenlySpacedLayout` | 均匀间隔 |
| `RandomLayout` | 自由定位(覆盖层) |

## `add(tamanho, comp)` —— 三种情形
```java
add(LAY_AUTO, comp);   //  0f → 内容的自然大小
add(LAY_FILL, comp);   // -1f → 填充剩余空间（“弹性”部分）
add(0.3f, comp);       // >0  → 容器尺寸的 30%
```

## 关键技巧:嵌套布局
真实界面是通过**组合**采用不同布局的容器搭建而成的。header 用 `HorizontalLayout`(自动),内容用 `LAY_FILL`,全部放在一个 `VerticalLayout` 里:
```java
setLayout(new VerticalLayout(Position.START, Position.START));

Component header = new Component();
header.setLayout(new HorizontalLayout(Position.START, Position.CENTER));
header.add(LAY_AUTO, new Button(new MaterialIcon("")));   // 图标
header.add(LAY_FILL, new Label("Minhas tarefas"));         // 标题吸收宽度
add(LAY_AUTO, header);                                      // header：自然高度

add(LAY_FILL, new VirtualListView(Relative.ofFont(3f), adapter));   // 列表：吸收高度
```

## 本步骤所构建的
列表界面的**最终结构**:**header**(自动)+ **列表**(`LAY_FILL`)+ 页脚。

## 回顾
`add(0f|-1f|分数, comp)`;每个轴上一个 `LAY_FILL` 就是弹性元素;为真实界面**嵌套布局**。

## 下一步
→ [样式与主题](/docs/learn/styling-and-themes)

## 另见
- [布局(ui)](/docs/ui/layouts) · 概念:[布局与 Relative 模型](/docs/concepts/the-layout-and-relative-model)
