5.9 KiB
修复 UI 边界溢出与记分页白屏问题
问题概述
- 记分页白屏(严重):进入记分页后白屏,由
OutlinedButton收到无限宽度约束导致整个Scaffold布局失败引起 - 首页环值分布卡片溢出:
score_distribution_card.dart:86Column 底部溢出 13px - 创建页数字选择器溢出:
point_book_create_page.dart:187Row 右侧溢出 14px
根因分析
白屏根因:SizedBox(height: size) 与 Expanded 的约束冲突
point_book_edit_page.dart 第 82-141 行的结构:
Expanded( // 给子节点 tight height = 剩余高度 (如 200px)
child: Padding(
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth; // 如 350px (屏幕宽度)
return SizedBox(
width: size, // 350
height: size, // 350 ← 与 Expanded 的 200px 冲突!
child: GestureDetector(...),
);
},
),
),
)
约束冲突原理:
Expanded给子节点BoxConstraints(minHeight: 200, maxHeight: 200)(tight)SizedBox(height: 350)给子节点BoxConstraints(minHeight: 350, maxHeight: 350)(tight)- 交集:
minHeight: max(200,350)=350, maxHeight: min(200,350)=200→ 350 > 200,不可能约束! - 布局失败级联到整个 Column → Scaffold → 白屏
环值分布卡片溢出根因
score_distribution_card.dart 第 84 行:maxH = constraints.maxHeight - 28
柱状图 _Bar 的 Column 内容总高度 = count文字(~15) + spacing(4) + bar(最大 maxH=112) + spacing(4) + label文字(~16) = 151px,但可用高度仅 140px,溢出 11-13px。
创建页溢出根因
point_book_create_page.dart 第 187 行:_NumberPicker 内的 Row 包含两个默认尺寸 IconButton(各 48px)+ 文字 + 标签文字,在半屏宽度内放不下。
修改方案
1. point_book_edit_page.dart — 修复白屏(关键)
文件:lib/features/scoring/presentation/point_book_edit_page.dart
行号:82-141
将 Expanded > Padding > LayoutBuilder > SizedBox 结构改为 Expanded > Padding > Center > AspectRatio > LayoutBuilder:
// 修改前(第 85-90 行):
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth;
return SizedBox(
width: size,
height: size,
child: GestureDetector(
// 修改后:
child: Center(
child: AspectRatio(
aspectRatio: 1.0,
child: LayoutBuilder(
builder: (context, constraints) {
final size = constraints.maxWidth;
return GestureDetector(
关键变更:
- 在
Padding和LayoutBuilder之间插入Center(child: AspectRatio(aspectRatio: 1.0)) - 删除
SizedBox(width: size, height: size)包装层 Center松解Expanded的 tight height 约束 →AspectRatio计算 min(宽,高) 的正方形 →LayoutBuilder获取的constraints.maxWidth == constraints.maxHeight→ 无冲突Image.asset和CustomPaint的size: Size(size, size)保持不变- 对应关闭括号:需要增加
),(AspectRatio) 和),(Center) 的闭合
2. point_book_create_page.dart — 修复 Row 溢出 14px
文件:lib/features/scoring/presentation/point_book_create_page.dart
行号:187-216(_NumberPicker 的 build 方法)
修改 _NumberPicker 中的两个 IconButton,使其更紧凑:
// 修改前(第 193-198 行):
IconButton(
icon: const Icon(Icons.remove_circle_outline),
onPressed: () {
// 修改后:
IconButton(
icon: const Icon(Icons.remove_circle_outline),
iconSize: 20,
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
onPressed: () {
同样修改 add 按钮(第 207-211 行)。
并将标签文字包裹 Flexible(第 190 行):
// 修改前:
Text(label, style: const TextStyle(fontSize: 13)),
// 修改后:
Flexible(
child: Text(label, style: const TextStyle(fontSize: 13)),
),
3. score_distribution_card.dart — 修复 Column 溢出 13px
文件:lib/features/home/presentation/widgets/score_distribution_card.dart
行号:第 84 行
// 修改前:
final maxH = constraints.maxHeight - 28; // reserve space for label
// 修改后:
final maxH = constraints.maxHeight - 40; // reserve space for count + label
将预留空间从 28px 增加到 40px,确保柱子最大高度不会导致 Column 溢出。
4. heatmap_card.dart — 修复 CustomPaint 尺寸为零(附带修复)
文件:lib/features/home/presentation/widgets/heatmap_card.dart
行号:第 29 行
当前 Stack 中 CustomPaint 没有指定 size,在 Stack 中默认尺寸为 0x0,导致命中点不可见。
// 修改前(第 29 行):
child: Stack(
alignment: Alignment.center,
children: [
// 修改后:
child: Stack(
fit: StackFit.expand,
alignment: Alignment.center,
children: [
添加 fit: StackFit.expand 使所有非定位子节点(Image.asset 和 CustomPaint)填满 Stack。
验证步骤
- 运行
flutter analyze确认无错误 - 启动 APP,进入首页 → 确认无黄色溢出条纹
- 点击"开始记分" → 进入创建页 → 确认数字选择器无溢出
- 完成创建 → 进入记分页 → 确认 不白屏,靶面正常显示
- 点击靶面 → 确认命中点准确渲染
- 返回首页 → 查看热力图 → 确认命中点可见