# 响应式设计：一套 UI 适配所有屏幕

> 屏幕自动适配尺寸、密度、字体缩放和方向——无需媒体查询。

Source: https://crossfly.dev/zh/docs/best-practices/responsividade — CrossFly documentation. Full docs as one file: https://crossfly.dev/llms-full.txt

# 响应式设计：一套 UI 适配所有屏幕

在 CrossFly 中，响应式设计**不是一个单独的功能**——它是按关系度量的结果。只要你遵循下面的原则，屏幕就会自动重新适配尺寸、密度（DPI）、字体缩放和方向，**无需媒体查询，也无需手动重新计算**。本页是第 36 章面向任务的摘选；其中的"为什么"请见 [布局与 Relative 模型](/docs/concepts/the-layout-and-relative-model)。

## 五大原则
1. **绝不用固定像素定位。** 使用分数、`Relative` 以及 `LAY_FILL`/`LAY_AUTO`。
2. **让布局来度量。** `LAY_AUTO`/`Relative.AUTO`/`RelSize.AUTOSIZE` 会报告自然尺寸。
3. **间距也要缩放。** 通过 `Gap.ofFont(...)` 设置 `ingap`/`outgap`，绝不用像素。
4. **每个轴一个弹性区域。** 用 `LAY_FILL` 标记**一个**组件来吸收剩余空间。
5. **调整尺寸是自动的**——只要你做到了上述几点。只有手动 `setBounds` 才需要写代码。

## 工具箱
| 工具 | 何时使用 |
|---|---|
| `Relative.ofFont(x)` | 需要随字体/DPI 缩放的尺寸（内含密度和缩放） |
| `Relative.ofScreen(x[, ScreenSize.MIN])` | 屏幕的分数；`MIN` = 适配竖屏/横屏 |
| `LAY_FILL` / `LAY_AUTO` / 分数 | 划分容器 |
| `Gap.ofFont(...)` | 可缩放的内边距/外边距 |
| `Screen.minSize` | 在方向之间稳定的**断点** |

## 用 `Screen.minSize` 设置断点
使用**较短边**（`Screen.minSize`），而非 `width`——当设备旋转时它保持稳定：
```java
boolean tablet = Screen.minSize >= 600;   // 例如决定 1 列还是 2 列
```

## 当（少数情况下）需要改变排布时：`onReposition()`
如果布局需要因方向而**改变结构**，请覆写 `Window.onReposition()`：
```java
@Override protected void onReposition() throws Exception {
   painel.removeAll();
   if (Screen.isLandscape) {                     // 2 列
      painel.setLayout(new HorizontalLayout());
      painel.add(0.5f, lista); painel.add(0.5f, detalhe);
   } else {                                       // 1 列
      painel.setLayout(new VerticalLayout());
      painel.add(LAY_FILL, lista); painel.add(LAY_AUTO, detalhe);
   }
}
```

## 响应式检查清单
- [ ] 零固定 `ofPixels`/`setBounds`（除非有正当理由的例外）。
- [ ] 每个弹性轴上恰好**一个** `LAY_FILL`。
- [ ] 间距使用 `Gap.ofFont`/`ofScreen`。
- [ ] 方块/图标使用 `ofScreen(v, ScreenSize.MIN)`。
- [ ] 断点使用 `Screen.minSize`。

## 反模式
| 反模式 | 修正 |
|---|---|
| `setBounds(0,0,300,48)` | `LAY_AUTO`/`Relative.ofFont` |
| 固定的 `Gap.ofPixels(16)` | `Gap.ofFont(1f)` |
| 用 `Screen.width` 设断点 | `Screen.minSize` |
| 同一轴上有两个 `LAY_FILL` | 只用一个 |

## 另请参阅
- 权威来源：第 36 章 · 概念：[布局与 Relative](/docs/concepts/the-layout-and-relative-model)
- [布局](/docs/ui/layouts) · [响应式设计（ui）](/docs/ui/layouts/responsiveness)
