v64b:修真机弹层"点了没反应"(根容器 Column → Stack)+ 日期行热区

四个日期/选择类浮层在真机上**完全打不开**:编译无告警、`aboutToAppear` 照常调用、
`dumpLayout` 里连弹层一个节点都看不到、点它会"穿透"到底下的列表。

根因(逐层二分定位):根容器写成 `Column` 且里面**先排一个整高遮罩**
(`Column().width('100%').height('100%').backgroundColor(FB_MASK)`)再排卡片。
`Column` 是**线性**布局 ⇒ 遮罩占满整高后,卡片被排到屏幕**外面**。
⇒ 全屏遮罩与卡片要"叠"(`Stack`),不能"排"(`Column`)。

改动:
- FbDateTimeField / FbCinemaPickSheet / FbPersonPickSheet:根容器改
  `Stack({ alignContent: Alignment.Center })`,遮罩与卡片作并列子项叠放;
  去掉原先用于"居中卡片"的 `justifyContent(FlexAlign.Center)`(Stack 已对齐)。
- FbDateTimeField:「日期行」的 `.onClick` 由内层 `layoutWeight(1)` 的 Row
  挪到**根 Row** —— 挂内层时那一行会被表单所在的**两列容器**盖住,
  点击穿透到底下的观影列表(表现为"点日期行,列表反而响应了")。
- FbSheetClose:`onClose` 由 `@Param` 改 `@Event`(语义归位;实测 `@Param`
  声明回调**并不会失效**,✕ 一直是能点的 —— 这不是本轮 bug 的根因,别混为一谈)。

验证:
- 构建 BUILD SUCCESSFUL;
- 静态守卫 644/0(新增 8 条:三个组件的 Stack 叠放 + 整高遮罩非空转 +
  全项目无"根 Column 先排整高遮罩"坏形态 + 日期行热区在根 Row);
- 守卫反向验证 92/0(新增 6 条注入,含把根 Stack 改回 Column、删遮罩、
  热区挪回内层,逐条证明断言真会红)。
This commit is contained in:
2026-10-20 08:55:27 +08:00
parent 8146aab1a7
commit 3b7238a418
4 changed files with 53 additions and 16 deletions
@@ -131,13 +131,21 @@ export struct FbDateTimeRow {
};
build() {
/*
* ⚠️ `.onClick` 挂在**根 `Row`** 上(整行可点),不是挂在里面那个
* `layoutWeight(1)` 的 `Row` 上 —— 2026-10-20 真机实测:
* 挂内层时,那一行会被表单所在的**两列容器**(dump 里两个
* `x1=50..521 / 559..1030、y1=602..1500` 的可点节点)盖住,
* 点击**穿透**到底下的观影列表(表现为"点日期行,列表反而响应了")。
* 根 `Row`(`.width('100%')`)与 `FbCalOptionRow` 同一形态,热区完整。
*/
Row({ space: 10 }) {
Text(this.label)
.fontSize(FbMetric.fontTiny)
.fontColor(FbColors.faint)
.width(28)
// 整块可点:日期与时间在**同一个控件**里,中间不再分两块
// 日期与时间在**同一个控件**里,中间不再分两块
Row() {
Text(fbCnDate(this.date))
.fontSize(FbMetric.fontSmall)
@@ -155,9 +163,6 @@ export struct FbDateTimeRow {
.backgroundColor(FbColors.inputBg)
.borderRadius(FbMetric.radiusS)
.alignItems(VerticalAlign.Center)
.onClick((): void => {
this.onTap();
})
// 右侧小箭头:暗示"点开会选"
Text('›')
@@ -166,6 +171,9 @@ export struct FbDateTimeRow {
}
.width('100%')
.alignItems(VerticalAlign.Center)
.onClick((): void => {
this.onTap();
})
}
}
@@ -209,7 +217,27 @@ export struct FbDateTimePicker {
}
build() {
Column() {
/*
* 🔴🔴 必须是 `Stack`,**不能**是 `Column`(2026-10-20 真机实测抓到的真 bug)。
*
* 错误形态(原先):
* Column() { // 根:线性布局
* Column().width('100%').height('100%') // ← 全屏遮罩
* Column() { ...卡片... } // ← 被挤到屏幕外
* }
* `Column` 是**线性**布局:遮罩占满整高之后,卡片只能排在它**下面**,
* 于是落到屏幕之外 —— 弹层"点了没反应"。
*
* 症状极具误导性(本轮排查花了很久,逐条记下):
* · 编译通过、无告警;`aboutToAppear` **确实被调用**(组件实例化了);
* · `dumpLayout` 里**完全看不到**弹层的任何节点(连插桩的 30 号红字都没有);
* · 点日期行会"穿透"到底下的观影列表(因为卡片不在屏幕内,点到的其实是列表);
* · 同文件的 `FbDateTimeRow`(没有遮罩)一直正常 —— 差异只在遮罩这一层。
* ⇒ 教训:**全屏遮罩与卡片要"叠"(Stack),不能"排"(Column)**。
* 项目里能用的浮层(`FbMovieInsightSheet`、`FbMovieDetailSheet`)都是
* `Column{ 卡片 }` 或 `Stack{ ... }`,**没有**把全屏遮罩当 Column 子项排的。
*/
Stack({ alignContent: Alignment.Center }) {
// 遮罩:整屏铺一层,点它 = 取消。
// ⚠️ 必须**有**遮罩:没有的话,点弹层外面会直接点到下面那张编辑卡片上
// (真机上表现为"随手一点,表单被改了")。
@@ -302,8 +330,6 @@ export struct FbDateTimePicker {
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
// ⚠️ 透明命中:让点击"卡片以外的区域"落到上面那层遮罩上(点遮罩关掉)
.hitTestBehavior(HitTestMode.Transparent)
}