# Responsividad

> Cómo garantizar que cualquier layout se adapte al tamaño de pantalla, densidad y fuente.

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

# Responsividad en todos los layouts

CrossFly usa **píxeles lógicos** y recalcula el layout al rotar/redimensionar. Si sigues los
principios de abajo, **la pantalla se readapta sola** — sin código de resize.

> Este es el resumen práctico. La guía completa, con un ejemplo en **cada** layout y un ejemplo de pantalla de
> extremo a extremo, es el Capítulo 36 — Buenas Prácticas de Layout y Responsividad.

## Los 5 principios
1. **Nunca posiciones en píxeles fijos.** Usa fracciones, `Relative` y `LAY_FILL`/`LAY_AUTO` / `RelSize.FILL`.
2. **Deja que el layout mida.** `LAY_AUTO`, `RelSize.AUTOSIZE` y `Relative.AUTO` reportan el tamaño natural.
3. **El espaciado también escala.** Padding (`ingap`) y margen (`outgap`) vía `Gap.ofFont(...)` / `Gap.ofScreen(...)`.
4. **Un área "elástica".** Marca **un** componente con `LAY_FILL` (Vertical/Horizontal) para absorber el sobrante.
5. **El resize es automático** — si usaste los elementos anteriores. Solo el posicionamiento manual (`setBounds`) exige código.

## La herramienta central: `Relative`
| Forma | Resultado |
|---|---|
| `Relative.ofFont(1.5f)` | 1,5 × altura de la fuente (escala con la fuente/DPI) |
| `Relative.ofScreen(0.8f)` | 80% de la dimensión de la pantalla |
| `Relative.ofScreen(0.5f, ScreenSize.MIN)` | 50% del lado **menor** (se adapta a portrait/landscape) |
| `Relative.FULL` / `AUTO` / `CENTER` | rellena el padre / tamaño de contenido / centra |

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

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

/** Pantalla principal ejecutable. Apunta el launcher (classname) y corre: gradlew :lwjgl3:run */
public class MainWindow extends Window
{
   private Component painel;      // reorganizado en cada resize/rotación
   private Component lista;
   private Component detalhe;

   @Override
   public void onShow() throws Exception
   {
      super.onShow();

      lista   = new Label("Lista");
      detalhe = new Label("Detalhe");

      painel = new Component();
      setLayout(new VerticalLayout(Position.START, Position.START));
      add(LAY_FILL, painel);
      // onReposition() se llama en el primer layout y en cada resize/rotación:
      // elige la disposición del panel según la orientación.
   }

   @Override
   protected void onReposition() throws Exception
   {
      painel.removeAll();
      if (Screen.isLandscape) {
         painel.setLayout(new HorizontalLayout());
         painel.add(0.5f, lista); painel.add(0.5f, detalhe);
      } else {
         painel.setLayout(new VerticalLayout());
         painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
      }
   }
}
```

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

## Cuándo el arreglo debe CAMBIAR por orientación
Sobrescribe `Window.onReposition()` (llamado antes del relayout) y vuelve a elegir el layout:
```java
@Override protected void onReposition() throws Exception {
   painel.removeAll();
   if (Screen.isLandscape) {
      painel.setLayout(new HorizontalLayout());
      painel.add(0.5f, lista); painel.add(0.5f, detalhe);
   } else {
      painel.setLayout(new VerticalLayout());
      painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
   }
}
```
**Breakpoints:** usa `Screen.minSize` (el lado menor es estable entre orientaciones), ej.: `tablet = Screen.minSize >= 600`.

## Ver también
- [Catálogo de layouts](/docs/ui/layouts) · Primitivas: `Relative`/`Gap`
