Appearance
font-scale-safe-area-demo
1. 实验目标
这个 Flutter host 实验专门验证 docs/12-screen-adaptation/03-font-scale-safe-area-foldables-and-validation.md 里最容易在真实项目漏掉的几类判断:
- 大字体:标题、列表项、表单、按钮在
1.0 / 1.3 / 1.6字体倍率下会不会裁切、拥挤、失去可点击性。 - 横向挤压:同一行里文本如果不拿
Expanded/Flexible,为什么会先被图标和按钮挤爆。 - 按钮高度:固定高度按钮和
minHeight + 弹性高度按钮在大字体下的差异。 - SafeArea:顶部状态栏 / 底部手势区为什么需要显式让出安全区。
- 键盘:输入框聚焦后,底部 CTA 是否会跟随
MediaQuery.viewInsets.bottom上移。
这个页面不是“堆组件”,而是把错误写法 / 正确写法并排放在同一页,方便你快速做工程判断。
2. 工程要点
- 用
MediaQuery.copyWith(textScaler: TextScaler.linear(x))在页面内局部模拟字体倍率,不依赖修改系统设置。 - 每个小节都保留对照区:左侧故意保留错误写法,右侧给出正确写法。
- 键盘区直接读取
MediaQuery.viewInsets.bottom,便于在真机 / 模拟器里看 CTA 是否随键盘抬升。 - SafeArea 区故意做成“模拟设备边界”,方便直观看到顶部和底部预留的差异。
3. 关键实现速览
3.1 局部模拟字体倍率
为什么看这段:它能在同一页面快速重现大字体问题,而不需要真的改系统字体设置。
dart
final simulatedMediaQuery = baseMediaQuery.copyWith(
textScaler: TextScaler.linear(_selectedFontScale),
);
return MediaQuery(
data: simulatedMediaQuery,
child: Scaffold(...),
);3.2 横向文本接管剩余空间
为什么看这段:它是“Row 挤压问题”最关键的修法。
dart
Row(
children: [
const Icon(Icons.check_circle_outline),
const SizedBox(width: 8),
Expanded(
child: Text(
'自动续费说明:这里故意放一段较长的标题文案,让文本自己接住横向压缩和字体放大。',
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
),
const SizedBox(width: 8),
FilledButton.tonal(onPressed: () {}, child: const Text('去处理')),
],
)3.3 键盘抬升底部 CTA
为什么看这段:很多“输入框页没适配”的线上反馈,根因就是底部操作区没有吃 viewInsets.bottom。
dart
final bottomInset = MediaQuery.viewInsetsOf(context).bottom;
final keyboardSpacer = showKeyboardInsetFix ? bottomInset : 0.0;
AnimatedContainer(
padding: EdgeInsets.fromLTRB(16, 12, 16, 12 + keyboardSpacer),
child: FilledButton.icon(...),
)完整源码:font_scale_safe_area_demo_page.dart
4. 运行方式
bash
cd labs/flutter/host
flutter pub get
flutter run启动后从首页进入 字体 / SafeArea / 键盘专项 Demo。
5. 预期现象
- 切到
1.3x / 1.6x后:- 错误卡片更容易出现标题拥挤、列表副标题被压扁、固定高度按钮显得局促。
- 正确卡片会通过
minHeight、换行、Expanded和可滚动容器兜住内容增长。
- 关闭
SafeArea 对照后:模拟设备里的顶部标题和底部 CTA 会更贴近黑色系统栏区域。 - 关闭
键盘 viewInsets 修复后:在真机 / 模拟器里点进输入框,底部 CTA 更容易被键盘压住。
6. 常见误区
| 误区 | 实际情况 |
|---|---|
| 字体适配就是把字号按设计稿缩放 | 错。字体首先服务可读性与无障碍,不应被 375 比例绑死。 |
文本写 sp / TextStyle 就够了 | 不够。容器高度、横向空间分配、整页滚动能力同样重要。 |
| SafeArea 能顺带解决键盘问题 | 错。SafeArea 处理系统栏边界,键盘还要看 viewInsets / ime。 |
| 把按钮高度固定住更整齐 | 只在默认字体下看起来整齐,大字体后往往最先出问题。 |
7. 对应知识库文档
- 理论主文档:字体、系统边界与动态窗口:屏幕适配的上线验收层
- 模块总览:屏幕适配:从清晰显示到动态窗口可用