# Cómo aplicar una transición al abrir/cerrar una pantalla

> Configurar una transición (slide, fade, scale) en el WindowStyle antes de show()/hide() — CrossFly anima el cambio de pantallas automáticamente.

Source: https://crossfly.dev/es/docs/cookbook/anim/transicao-de-tela — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# Cómo aplicar una transición al abrir/cerrar una pantalla

**Propósito.** A diferencia de las animaciones de valor (que tú mismo diriges), una **transición de pantalla** es aplicada por el framework al apilar/desapilar una `Window`. Basta con configurarla en el `WindowStyle` **antes** de `show()`; el `hide()` ejecuta la transición **inversa** automáticamente.

## APIs usadas
- `WindowStyle.transition(UIConstants.Transition t)` — define el efecto (duración por defecto 0.5s).
- `WindowStyle.transition(Transition t, float durationSeconds)` — efecto + duración juntos.
- `WindowStyle.transitionDuration(float d)` — solo la duración.
- `WindowStyle.transition` (campo) — por defecto `Transition.NONE` (sin animación).
- `UIConstants.Transition` — enum: `NONE, FADE, SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN, SCALE, SCALE_DOWN`. Al ocultar, el framework usa `t.reverse()` (ej.: `SLIDE_LEFT` → `SLIDE_RIGHT`, `SCALE` → `SCALE_DOWN`).
- `Window.getStyle()` — retorna el `ComponentStyle`; para una `Window` es un `WindowStyle`.

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

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

/** Pantalla principal ejecutable: abre OutraTela con una transición SLIDE_LEFT. */
public class MainWindow extends Window
{
   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());

      add(new Label("Tela inicial"));
      add(new Button("Abrir detalhe").onAction(e -> new OutraTela().show()));  // desliza desde la derecha
   }
}

/** Pantalla apilada: configura la transición en el constructor; hide() corre el reverso (SLIDE_RIGHT). */
class OutraTela extends Window
{
   public OutraTela()
   {
      // configura la transición en el style ANTES de mostrar
      ((WindowStyle) getStyle()).transition(UIConstants.Transition.SLIDE_LEFT, 0.4f);
   }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new VerticalLayout());
      add(new Label("Detalhe"));
      add(new Button("Voltar").onAction(e -> hide()));  // hide() corre SLIDE_RIGHT (reverso) automáticamente
   }
}
```

> El fragmento de abajo muestra **solo el núcleo**. Para ejecutarlo, colócalo en el esqueleto `MainWindow` de arriba.

## Fragmento mínimo
```java
// verificado en la fuente: Window._show() dispara ScreenTransition.begin(ws.transition, ws.transitionDuration)
//                       Window.hide() dispara la transición inversa (ws.transition.reverse())
public class DetalheTela extends Window
{
   public DetalheTela()
   {
      // configura la transición en el style ANTES de mostrar
      ((WindowStyle) getStyle()).transition(UIConstants.Transition.SLIDE_LEFT, 0.4f);
   }

   @Override
   public void onShow() throws Exception
   {
      super.onShow();
      setLayout(new GridLayout());
      add(new Label("Detalhe"));
      add(new Button("Voltar").onAction(e -> hide()));  // hide() corre SLIDE_RIGHT (reverso) automáticamente
   }
}

// abrir con la transición:
new DetalheTela().show();     // desliza de la derecha a la izquierda
```

Notas:

- La transición se lee en `_show()`/`hide()` a partir del `WindowStyle`. Configúrala en el **constructor** o en cualquier punto antes de `show()` — cambiarla después de mostrada no reanima la entrada.
- **No** llames a `hide()` con una transición diferente esperando controlar la salida: la salida es siempre el **inverso** de lo que estaba configurado (`transition.reverse()`).
- `Picker` ya usa `FADE` por defecto (se fuerza en `Picker._show()` si está en `NONE`) — raramente necesitas configurar transición en pickers.
- Estas transiciones animan el **cambio entre pantallas** (la `Window` entera). Para animar un componente aislado dentro de la pantalla, usa las animaciones de valor ([Fade](/docs/cookbook/anim/fade), [Mover](/docs/cookbook/anim/mover-componente), [Pulso](/docs/cookbook/anim/pulso-loop)).

## Profundiza
- [Transiciones de pantalla](/docs/ui/animations/screen-transitions)
- Receta hermana: [Fade de un componente](/docs/cookbook/anim/fade)
- Relacionado: [Abrir y cerrar una pantalla](/docs/cookbook/nav/abrir-tela)
