diff --git a/entry/src/main/ets/components/FbCinemaPickSheet.ets b/entry/src/main/ets/components/FbCinemaPickSheet.ets index e30d325..d737bb6 100644 --- a/entry/src/main/ets/components/FbCinemaPickSheet.ets +++ b/entry/src/main/ets/components/FbCinemaPickSheet.ets @@ -80,8 +80,12 @@ export struct FbCinemaPickSheet { } build() { - // 整屏遮罩 + 居中卡片(与全应用浮层同一形态) - Column() { + /* 🔴🔴 必须是 `Stack`,**不能**是 `Column`(2026-10-20 真机实测的真 bug)。 + `Column` 是**线性**布局:全屏遮罩(100% 高)会占满整高, + 卡片被排到它**下面** ⇒ 落到屏幕之外 ⇒ 弹层"点了没反应"。 + 症状:编译无告警、dumpLayout 里看不到弹层任何节点、点击会穿透到下层。 + ⇒ **全屏遮罩与卡片要"叠"(Stack),不能"排"(Column)**。 */ + Stack({ alignContent: Alignment.Center }) { Column() .width('100%') .height('100%') @@ -181,7 +185,6 @@ export struct FbCinemaPickSheet { } .width('100%') .height('100%') - .justifyContent(FlexAlign.Center) .hitTestBehavior(HitTestMode.Transparent) } diff --git a/entry/src/main/ets/components/FbDateTimeField.ets b/entry/src/main/ets/components/FbDateTimeField.ets index fee0432..7b0b63d 100644 --- a/entry/src/main/ets/components/FbDateTimeField.ets +++ b/entry/src/main/ets/components/FbDateTimeField.ets @@ -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) } diff --git a/entry/src/main/ets/components/FbPersonPickSheet.ets b/entry/src/main/ets/components/FbPersonPickSheet.ets index 6daf08d..035a72c 100644 --- a/entry/src/main/ets/components/FbPersonPickSheet.ets +++ b/entry/src/main/ets/components/FbPersonPickSheet.ets @@ -144,7 +144,11 @@ export struct FbPersonPickSheet { } build() { - Column() { + /* 🔴🔴 必须是 `Stack`,**不能**是 `Column`(2026-10-20 真机实测的真 bug)。 + 原因与 `FbCinemaPickSheet` 那段完全相同:`Column` 是线性布局, + 全屏遮罩会占满整高、把卡片挤到屏幕外 ⇒ 弹层"点了没反应"。 + ⇒ **全屏遮罩与卡片要"叠"(Stack),不能"排"(Column)**。 */ + Stack({ alignContent: Alignment.Center }) { Column() .width('100%') .height('100%') @@ -350,7 +354,6 @@ export struct FbPersonPickSheet { } .width('100%') .height('100%') - .justifyContent(FlexAlign.Center) .hitTestBehavior(HitTestMode.Transparent) } } diff --git a/entry/src/main/ets/components/FbSheetClose.ets b/entry/src/main/ets/components/FbSheetClose.ets index 4fc66c4..a6fabd3 100644 --- a/entry/src/main/ets/components/FbSheetClose.ets +++ b/entry/src/main/ets/components/FbSheetClose.ets @@ -31,10 +31,14 @@ export struct FbSheetClose { /** * 关掉浮层。 * - * ⚠️ 必传:`@Param` 给不了函数默认值(ArkTS 里函数类型不能用常量表达式初始化), - * 所以这里用必填 + 各调用点都显式给。 + * 用 `@Event`:`@ComponentV2` 里回调**一律**用 `@Event`(数据入参才用 `@Param`, + * 见 `FbCalOptionRow.onPick` 等)。原先写的是 `@Param` —— + * ⚠️ 实测(2026-10-20 真机)`@Param` 声明回调**并不会失效**(✕ 是能点的), + * 所以这不是 bug;改过来只是**把语义摆正**,别让下一个人以为它会失效。 + * 本轮真正导致"弹层点了没反应"的是**根容器 `Column` → `Stack`** + * (线性布局把卡片挤出屏幕),与本文件无关,别混为一谈。 */ - @Param onClose: () => void = (): void => {}; + @Event onClose: () => void = (): void => {}; /** * 图标的颜色。 @@ -92,7 +96,8 @@ export struct FbSheetTitleBar { @Param confirmText: string = ''; /** 主题色(标题下的副标题、确认文字用它) */ @Param accent: string = ''; - @Param onClose: () => void = (): void => {}; + /** 同上:回调统一 `@Event`(`@Param` 实测也能用,但语义不对) */ + @Event onClose: () => void = (): void => {}; build() { Row({ space: 8 }) {