# TextField 垂直居中问题

**问题标签**: `textfield`, `居中`, `placeholder`, `光标`, `输入框`, `vertical-align`  
**问题类型**: `UI 对齐`  
**严重程度**: 高  
**节省时间**: 15+ 轮对话 → 1 轮

---

## 问题描述

TextField 中 placeholder、光标、输入内容三者需要在固定高度容器中垂直居中对齐，但出现以下问题：
- placeholder 和输入内容位置不一致
- 光标位置偏上或偏下
- 修改一个问题引发另一个问题

## 问题根因

Flutter TextField 的垂直对齐涉及多个相互作用的属性：
- `style.height` - 输入文本的行高
- `hintStyle.height` - placeholder 的行高
- `contentPadding` - 内边距
- `isDense` - 紧凑模式
- `textAlignVertical` - 垂直对齐
- `strutStyle` - 行高基准

**核心问题**：这些属性相互影响，单独调整一个可能破坏其他元素的对齐。

## 错误尝试（导致反复）

| 尝试 | 结果 |
|------|------|
| 只调整 `contentPadding` | 整体偏移，不居中 |
| 用 `textAlignVertical: center` | 只影响输入内容，placeholder 不动 |
| 用 `strutStyle + forceStrutHeight` | 文字被压缩变形 |
| `style.height` ≠ `hintStyle.height` | placeholder 和输入内容位置不一致 |

## 正确方案

### 从设计稿获取数值

```javascript
// Sketch 提取脚本
const container = sketch.find('[name="Input"]', artboard)[0];
const text = container.layers.find(l => l.type === 'Text');

console.log(`容器高度: ${container.frame.height}px`);        // 36
console.log(`文本 Y 坐标: ${text.frame.y}px`);               // 8
console.log(`文本高度: ${text.frame.height}px`);              // 20
console.log(`字号: ${text.style.fontSize}px`);                // 14
console.log(`行高倍数: ${text.frame.height / text.style.fontSize}`);  // 1.43
```

### Flutter 代码

```dart
Container(
  height: 36, // 设计稿容器高度
  alignment: Alignment.center, // 关键1：让 TextField 整体居中
  child: TextField(
    textAlign: TextAlign.center,
    style: const TextStyle(
      fontSize: 14,
      height: 1.43, // 关键2：行高 = 文本高度÷字号 = 20÷14
    ),
    decoration: InputDecoration(
      hintText: placeholder,
      hintStyle: const TextStyle(
        fontSize: 14,
        height: 1.43, // 关键3：必须与 style.height 完全一致
      ),
      contentPadding: EdgeInsets.zero, // 关键4：清除默认 padding
      isDense: true, // 关键5：移除额外空间
      border: InputBorder.none,
    ),
  ),
)
```

## 关键原则

| 原则 | 说明 |
|------|------|
| `style.height` = `hintStyle.height` | 两者必须相同，否则位置不一致 |
| `Container.alignment` 控制居中 | 不要用 `textAlignVertical` |
| `contentPadding: EdgeInsets.zero` | 让 Container.alignment 生效 |
| 先计算再编码 | 行高 = 文本高度 ÷ 字号 |

## 禁止事项

- ❌ `style.height` ≠ `hintStyle.height`
- ❌ 同时使用 `textAlignVertical` 和 `height`
- ❌ 使用 `strutStyle + forceStrutHeight`
- ❌ 反复调整 `contentPadding` 试错

## 验证方法

1. 点击输入框，检查光标位置
2. 输入文字，检查文字位置
3. 清空输入，检查 placeholder 位置
4. 三者应该在同一垂直位置

---

**案例来源**: 汇款记录筛选弹窗金额输入框  
**创建日期**: 2026-01-19  
**版本**: v1.0
