# RelativeLayout

> Posiciona e dimensiona por âncoras — relativo ao contêiner ou a outro componente.

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

# RelativeLayout

Posiciona cada filho por **âncoras** — relativas ao contêiner **ou a outro componente**. Sua força
única é **ancorar A a B** (um badge no canto de um avatar, um rótulo à direita de um ícone).

> 🔴 · **Pacote:** `dev.crossfly.ui.layout` · **Estende:** `Layout`

## Quando usar
- Ancorar um componente a **outro** (`AFTER`, `BEFORE`, `END_OF`, `CENTER_OF`).
- Sobreposições e composições finas (badge, selo, rótulo posicionado).

## Quando NÃO usar
- Esqueleto "topo/conteúdo/base preenchendo a sobra" → **prefira** [VerticalLayout](/docs/ui/layouts/vertical-layout)
  com `LAY_FILL` (mais simples; ver a nota sobre `FILL`/`FIT` abaixo).

## `add(...)` — assinatura e semântica
```java
public RelativeLayout add(Component alvo, RelPos x, RelPos y, RelSize larg, RelSize alt);
// + sobrecargas:  (..., Component ref)   (..., Gap outgap)   (..., Component ref, Gap outgap)
```
Sem `ref`, a âncora é relativa ao **componente anterior** adicionado.

**`RelPos`** (posição, em `UIConstants`): `START`, `CENTER`, `END`, `AFTER`, `BEFORE`, `CENTER_OF`,
`END_OF`, `SAMEPOS`, `AUTOPOS`, `AUTOPOSCENTERED`, `KEEPPOS`.

**`RelSize`** (tamanho): `AUTOSIZE`, `FILL`, `FIT`, `SAMESIZE`, `KEEPSIZE`.

## Exemplo completo (copiar, colar e rodar)
```java
package com.exemplo;

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

/** Tela principal executável. Aponte o launcher (classname) e rode: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      // Avatar + badge no canto do avatar + nome ao lado
      RelativeLayout rl = new RelativeLayout();
      Label avatar = new Label("👤");
      avatar.getStyle().autoWidth(Relative.ofFont(3f)).autoHeight(Relative.ofFont(3f));
      Label badge = new Label("9");
      Label nome  = new Label("Ana Silva");

      rl.add(avatar, RelPos.START,  RelPos.START,     RelSize.AUTOSIZE, RelSize.AUTOSIZE);
      rl.add(badge,  RelPos.END_OF, RelPos.START,     RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // canto do avatar
      rl.add(nome,   RelPos.AFTER,  RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // após o avatar

      Component cabecalho = new Component();
      cabecalho.setLayout(rl);

      setLayout(new VerticalLayout(Position.START, Position.START));
      add(LAY_AUTO, cabecalho);
      add(LAY_FILL, new Component());
   }
}
```

> Os trechos abaixo mostram **só o miolo** (o que vai dentro de `onShow()`). Para rodar, coloque-os no esqueleto `MainWindow` acima.

## Uso básico
```java
// Avatar + badge no canto do avatar + nome ao lado
RelativeLayout rl = new RelativeLayout();
ImageView avatar = new ImageView(/* foto */);
avatar.getStyle().autoWidth(Relative.ofFont(3f)).autoHeight(Relative.ofFont(3f));
Label badge = new Label("9");
Label nome  = new Label("Ana Silva");

rl.add(avatar, RelPos.START,  RelPos.START,     RelSize.AUTOSIZE, RelSize.AUTOSIZE);
rl.add(badge,  RelPos.END_OF, RelPos.START,     RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // canto do avatar
rl.add(nome,   RelPos.AFTER,  RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // após o avatar

Component cabecalho = new Component();
cabecalho.setLayout(rl);
```

## Padrões úteis de âncora
- **B à direita de A, alinhado:** `add(b, RelPos.AFTER, RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, a)`.
- **Mesmo tamanho de A:** `RelSize.SAMESIZE`.
- **Card centralizado:** `add(card, RelPos.CENTER, RelPos.CENTER, RelSize.AUTOSIZE, RelSize.AUTOSIZE)`.
- **Margem por regra:** passe um `Gap.ofFont(0.5f)` como último argumento (vira o `outgap` da regra).

## ⚠️ Semântica exata de `RelSize` (não confunda)
- **`FILL`** = largura/altura **total do pai** menos a margem — **ignora a referência** (não é "o
  espaço restante ao lado de A").
- **`FIT`** = do **canto do pai até a borda da referência** (ex.: preencher **até** a esquerda/topo de A).
- Para "um filho absorve a sobra ao lado dos outros" → use `HorizontalLayout`/`VerticalLayout` com
  `LAY_FILL`, **não** o `RelativeLayout`.

## Erros comuns
- Esperar que `FILL` seja "o que sobra ao lado de A" (é o pai inteiro).
- **Ciclos** de referência (A depende de B que depende de A) — ancore sempre em componentes já
  adicionados antes.

## Veja também
- [VerticalLayout](/docs/ui/layouts/vertical-layout) (para o esqueleto de tela) · [Responsividade](/docs/ui/layouts/responsiveness)
