# RelativeLayout

> Posiciona y dimensiona por anclas — relativo al contenedor o a otro componente.

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

# RelativeLayout

Posiciona cada hijo por **anclas** — relativas al contenedor **o a otro componente**. Su fortaleza
única es **anclar A a B** (un badge en la esquina de un avatar, una etiqueta a la derecha de un icono).

> 🔴 · **Paquete:** `dev.crossfly.ui.layout` · **Extiende:** `Layout`

## Cuándo usar
- Anclar un componente a **otro** (`AFTER`, `BEFORE`, `END_OF`, `CENTER_OF`).
- Superposiciones y composiciones finas (badge, sello, etiqueta posicionada).

## Cuándo NO usar
- Esqueleto "arriba/contenido/base rellenando el sobrante" → **prefiere** [VerticalLayout](/docs/ui/layouts/vertical-layout)
  con `LAY_FILL` (más simple; ver la nota sobre `FILL`/`FIT` abajo).

## `add(...)` — firma y 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)
```
Sin `ref`, el ancla es relativa al **componente anterior** añadido.

**`RelPos`** (posición, en `UIConstants`): `START`, `CENTER`, `END`, `AFTER`, `BEFORE`, `CENTER_OF`,
`END_OF`, `SAMEPOS`, `AUTOPOS`, `AUTOPOSCENTERED`, `KEEPPOS`.

**`RelSize`** (tamaño): `AUTOSIZE`, `FILL`, `FIT`, `SAMESIZE`, `KEEPSIZE`.

## Ejemplo completo (copiar, pegar y ejecutar)
```java
package com.exemplo;

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      // Avatar + badge en la esquina del avatar + nombre al 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); // esquina del avatar
      rl.add(nome,   RelPos.AFTER,  RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // después del avatar

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

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

> Los fragmentos siguientes muestran **solo el núcleo** (lo que va dentro de `onShow()`). Para ejecutar, colócalos en el esqueleto `MainWindow` anterior.

## Uso básico
```java
// Avatar + badge en la esquina del avatar + nombre al 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); // esquina del avatar
rl.add(nome,   RelPos.AFTER,  RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, avatar); // después del avatar

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

## Patrones útiles de ancla
- **B a la derecha de A, alineado:** `add(b, RelPos.AFTER, RelPos.CENTER_OF, RelSize.AUTOSIZE, RelSize.AUTOSIZE, a)`.
- **Mismo tamaño que A:** `RelSize.SAMESIZE`.
- **Card centrado:** `add(card, RelPos.CENTER, RelPos.CENTER, RelSize.AUTOSIZE, RelSize.AUTOSIZE)`.
- **Margen por regla:** pasa un `Gap.ofFont(0.5f)` como último argumento (se convierte en el `outgap` de la regla).

## ⚠️ Semántica exacta de `RelSize` (no confundir)
- **`FILL`** = ancho/alto **total del padre** menos el margen — **ignora la referencia** (no es "el
  espacio restante junto a A").
- **`FIT`** = desde la **esquina del padre hasta el borde de la referencia** (ej.: rellenar **hasta** la izquierda/arriba de A).
- Para "un hijo absorbe el sobrante junto a los demás" → usa `HorizontalLayout`/`VerticalLayout` con
  `LAY_FILL`, **no** el `RelativeLayout`.

## Errores comunes
- Esperar que `FILL` sea "lo que sobra junto a A" (es el padre entero).
- **Ciclos** de referencia (A depende de B que depende de A) — ancla siempre en componentes ya
  añadidos antes.

## Ver también
- [VerticalLayout](/docs/ui/layouts/vertical-layout) (para el esqueleto de pantalla) · [Responsividad](/docs/ui/layouts/responsiveness)
