# 如何在打开/关闭屏幕时应用过渡效果

> 在 show()/hide() 之前于 WindowStyle 中配置过渡效果（slide、fade、scale）——CrossFly 会自动为屏幕切换添加动画。

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

# 如何在打开/关闭屏幕时应用过渡效果

**目的。** 与值动画（由你自己驱动）不同，**屏幕过渡**是由框架在压入/弹出 `Window` 时应用的。你只需在 `show()` **之前**于 `WindowStyle` 中配置它；`hide()` 会自动运行**反向**过渡。

## 使用的 API
- `WindowStyle.transition(UIConstants.Transition t)` —— 设置效果（默认时长 0.5s）。
- `WindowStyle.transition(Transition t, float durationSeconds)` —— 同时设置效果 + 时长。
- `WindowStyle.transitionDuration(float d)` —— 仅设置时长。
- `WindowStyle.transition`（字段）—— 默认 `Transition.NONE`（无动画）。
- `UIConstants.Transition` —— 枚举：`NONE, FADE, SLIDE_LEFT, SLIDE_RIGHT, SLIDE_UP, SLIDE_DOWN, SCALE, SCALE_DOWN`。隐藏时，框架使用 `t.reverse()`（例如：`SLIDE_LEFT` → `SLIDE_RIGHT`，`SCALE` → `SCALE_DOWN`）。
- `Window.getStyle()` —— 返回 `ComponentStyle`；对于 `Window` 而言即 `WindowStyle`。

## 完整示例（复制、粘贴并运行）
```java
package com.exemplo;

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

/** 可执行的主界面：以 SLIDE_LEFT 转场打开 OutraTela。 */
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()));  // 从右侧滑入
   }
}

/** 入栈界面：在构造函数中配置转场；hide() 运行反向（SLIDE_RIGHT）。 */
class OutraTela extends Window
{
   public OutraTela()
   {
      // 在显示前在 style 中配置转场
      ((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() 自动运行 SLIDE_RIGHT（反向）
   }
}
```

> 下面的代码片段仅展示**核心部分**。要运行它，请将其放入上面的 `MainWindow` 骨架中。

## 最小片段
```java
// 已在源码核实：Window._show() 触发 ScreenTransition.begin(ws.transition, ws.transitionDuration)
//                       Window.hide() 触发反向转场（ws.transition.reverse()）
public class DetalheTela extends Window
{
   public DetalheTela()
   {
      // 在显示前在 style 中配置转场
      ((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() 自动运行 SLIDE_RIGHT（反向）
   }
}

// 以转场打开：
new DetalheTela().show();     // 从右向左滑动
```

注意事项：

- 过渡效果在 `_show()`/`hide()` 中从 `WindowStyle` 读取。请在**构造函数**中或在 `show()` 之前的任意位置配置它——在已经显示之后再更改它不会重新播放进入动画。
- **不要**用不同的过渡效果调用 `hide()` 来期望控制退出：退出始终是所配置效果的**反向**（`transition.reverse()`）。
- `Picker` 默认已使用 `FADE`（如果处于 `NONE`，会在 `Picker._show()` 中被强制设置）——你几乎不需要为 picker 配置过渡效果。
- 这些过渡为**屏幕之间的切换**（整个 `Window`）添加动画。要为屏幕内的单个组件添加动画，请使用值动画（[淡入淡出](/docs/cookbook/anim/fade)、[移动](/docs/cookbook/anim/mover-componente)、[脉冲](/docs/cookbook/anim/pulso-loop)）。

## 深入了解
- [屏幕过渡](/docs/ui/animations/screen-transitions)
- 姊妹配方：[组件的淡入淡出](/docs/cookbook/anim/fade)
- 相关：[打开和关闭屏幕](/docs/cookbook/nav/abrir-tela)
