修「点头像没反应」:FbPersonSheet 塞进 bindSheet 会被立刻关掉(宿主契约冲突)
真机验证时抓到 —— 三条里第 ① 条第一轮**完全没用**:
点头像什么都不出来。每次点击日志都出现一组:
AceSheet: radius is not correct type
AceDrag: Drag gesture has been canceled ← 浮层起来立刻被取消
⇒ sheet **确实创建了**,但被测量失败关掉;界面上看就是"点了没反应"。
(我第一轮据此误判成 "onClick 没接上",白查了一轮点击链路 —— 点击是好的。)
根因:FbPersonSheet 的根节点是
Column() { /* 92% 宽的圆角卡 */ }
.width('100%').height('100%').justifyContent(FlexAlign.Center)
—— "铺满全屏 + 内部居中",因为它的**设计宿主**是
"页面里叠一层遮罩 + Stack 居中"(名册页、日程页都这么用)。
而 bindSheet 要求内容**按自身高度自适应** ⇒
"内容要铺满 100% 高" vs "sheet 要按内容定高" 互相打架 ⇒ 判为无效、立刻关。
修法(最小侵入,老调用点一个字不改):
① 给 FbPersonSheet 加 `@Param embedded: boolean = false`:
.width(this.embedded ? 'auto' : '100%')
.height(this.embedded ? 'auto' : '100%')
.justifyContent(this.embedded ? FlexAlign.Start : FlexAlign.Center)
.padding(bottom 在 embedded 时去掉"贴底手势区留白"那 16)
⇒ 默认 false = 老行为;顶栏那处传 embedded: true。
② sheet 高度用 SheetSize.LARGE 而不是 FIT_CONTENT
(卡片自带 maxHeight:72%,FIT_CONTENT 下会跟它抢高度)。
③ 删掉外层 myDetailPanel 上的 constraintSize({maxHeight:'82%'})
—— 高度由 sheet 定,三方都设 = 三方打架。
真机复验(装机后立即点):
浮层完整弹出且用的是**接口那份完整数据**(含本地没有的字段):
「杨永全 · 副教授 · 家中排行第 2 个 · 生日 11-16 · 邮箱 i@yangyq.net ·
地址 青岛市 · 身份证 372****4856 · 其它邮箱 yangyq@ouc.edu.cn ·
网址 https://yangyq.net · 工作经历 中国海洋大学|副教授」+ [编辑][关闭]
客观判据:uitest dumpLayout 的布局树字节数 119207 → 162736。
验证:hvigor BUILD SUCCESSFUL;_fb_arkts_guard.js 352/0(再增 5 条钉住
embedded / SheetSize.LARGE / 不铺满 / 组件有开关);_fb_v59b_falsify.py 11/0。
另修一条旧断言(L 组"不再占满宽"原来锚死 `width('92%')` 字面量,
放宽为接受条件式,但没退化成"文件里有 92% 就行")。
This commit is contained in:
@@ -56,6 +56,27 @@ export struct FbPersonSheet {
|
|||||||
*/
|
*/
|
||||||
@Event onEdit: () => void = (): void => {
|
@Event onEdit: () => void = (): void => {
|
||||||
};
|
};
|
||||||
|
/**
|
||||||
|
* 嵌入模式:宿主**自己已经是浮层**(如 `bindSheet`)时为 true。
|
||||||
|
*
|
||||||
|
* 🔴🔴 为什么必须有这个开关(2026-10-18 真机踩出来的真 bug):
|
||||||
|
* 本组件的根节点是 `Column().width('100%').height('100%')`(**铺满全屏**、
|
||||||
|
* 内部再垂直居中那张 92% 宽的卡)—— 因为它的设计宿主是
|
||||||
|
* "页面里叠一层遮罩 + Stack 居中"(名册页就是这么用的)。
|
||||||
|
*
|
||||||
|
* 而顶栏点头像想复用这个组件时,我把它塞进了 `bindSheet`:
|
||||||
|
* **sheet 要做"高度自适应内容"(`SheetSize.FIT_CONTENT`),
|
||||||
|
* 内容却要求"铺满 100% 高度"** ⇒ 测量互相打架。
|
||||||
|
* 真机症状:**每次点击 `AceSheet` 都创建了,却紧接着
|
||||||
|
* `AceDrag: Drag gesture has been canceled` —— 浮层起来立刻被关掉**
|
||||||
|
* (界面看上去"点了没反应",最容易被误判成"点击没接上")。
|
||||||
|
*
|
||||||
|
* ⇒ `embedded = true` 时:去掉 `width/height 100%` 与内层居中,
|
||||||
|
* 只留那张卡(宽度交给 sheet、高度自适应),sheet 自己负责
|
||||||
|
* 底部手势区与遮罩。
|
||||||
|
* ⚠️ 默认 `false` = 老行为,**名册/日程那几个调用点一个字都不用改**。
|
||||||
|
*/
|
||||||
|
@Param embedded: boolean = false;
|
||||||
|
|
||||||
/** 一行的图标资源 */
|
/** 一行的图标资源 */
|
||||||
private iconOf(name: string): Resource {
|
private iconOf(name: string): Resource {
|
||||||
@@ -465,17 +486,29 @@ export struct FbPersonSheet {
|
|||||||
// **不要让它左右充满整个屏幕,下面也不要挨着屏幕**,
|
// **不要让它左右充满整个屏幕,下面也不要挨着屏幕**,
|
||||||
// 而是放在**屏幕中间**,采用**圆角浮窗**式的形式。」
|
// 而是放在**屏幕中间**,采用**圆角浮窗**式的形式。」
|
||||||
// ⇒ 不再贴底满宽:左右留边(92%)、四角圆角、垂直居中(由宿主的 Stack 对齐)。
|
// ⇒ 不再贴底满宽:左右留边(92%)、四角圆角、垂直居中(由宿主的 Stack 对齐)。
|
||||||
.width('92%')
|
//
|
||||||
|
// ⚠️ `embedded`(宿主自己就是 sheet)时宽度交给 sheet 决定 ——
|
||||||
|
// 再用 92% 会在 sheet 里又缩一次,看上去"卡片比容器窄一圈"。
|
||||||
|
.width(this.embedded ? 'auto' : '92%')
|
||||||
// 最多占屏幕 72%:上方留出可见列表,暗示"这是浮层、下面还有内容"
|
// 最多占屏幕 72%:上方留出可见列表,暗示"这是浮层、下面还有内容"
|
||||||
.constraintSize({ maxHeight: '72%' })
|
.constraintSize({ maxHeight: this.embedded ? '100%' : '72%' })
|
||||||
.padding({ left: 18, right: 18, top: 18, bottom: 20 + FB_SHEET_BOTTOM_GAP })
|
// ⚠️ embedded 时**去掉底部手势区那段留白**:那 16 是给
|
||||||
|
// "贴底遮罩 + 隐藏手势条"的场景补的(见 FB_SHEET_BOTTOM_GAP),
|
||||||
|
// 而 bindSheet 自己已经把手势区让出来了 ⇒ 再补就是白白多一截空白。
|
||||||
|
.padding({
|
||||||
|
left: 18, right: 18, top: 18,
|
||||||
|
bottom: this.embedded ? 20 : 20 + FB_SHEET_BOTTOM_GAP
|
||||||
|
})
|
||||||
.backgroundColor(FbColors.surface)
|
.backgroundColor(FbColors.surface)
|
||||||
.borderRadius(FbMetric.radius)
|
.borderRadius(FbMetric.radius)
|
||||||
.alignItems(HorizontalAlign.Start)
|
.alignItems(HorizontalAlign.Start)
|
||||||
}
|
}
|
||||||
.width('100%')
|
/* 🔴 embedded(宿主自己就是 sheet)时**不能再铺满 + 居中**:
|
||||||
.height('100%')
|
内容是"按自适应高度"交给 sheet 的,铺 100% 高会与
|
||||||
.justifyContent(FlexAlign.Center)
|
`SheetSize.FIT_CONTENT` 互相打架 ⇒ 浮层起来立刻被关(真机实测)。 */
|
||||||
|
.width(this.embedded ? 'auto' : '100%')
|
||||||
|
.height(this.embedded ? 'auto' : '100%')
|
||||||
|
.justifyContent(this.embedded ? FlexAlign.Start : FlexAlign.Center)
|
||||||
.hitTestBehavior(HitTestMode.Transparent)
|
.hitTestBehavior(HitTestMode.Transparent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,10 @@ export struct FbTopBar {
|
|||||||
// ⚠️ `onDisappear` 必须复位 `myDetailSheet`(点遮罩/下滑关闭都会走它),
|
// ⚠️ `onDisappear` 必须复位 `myDetailSheet`(点遮罩/下滑关闭都会走它),
|
||||||
// 否则下次点头像**打不开**(状态位还是 true 但面板已经不在)。
|
// 否则下次点头像**打不开**(状态位还是 true 但面板已经不在)。
|
||||||
.bindSheet(this.myDetailSheet, this.myDetailPanel(), {
|
.bindSheet(this.myDetailSheet, this.myDetailPanel(), {
|
||||||
height: SheetSize.FIT_CONTENT,
|
// ⚠️ 用 `LARGE`(= 大高度、内容自适应)而不是 `FIT_CONTENT`:
|
||||||
|
// 详情卡片有 `maxHeight: '72%'` 的内部约束,FIT_CONTENT 下
|
||||||
|
// 系统会试图把 sheet 压到"刚好包住内容",与那个百分比约束打架。
|
||||||
|
height: SheetSize.LARGE,
|
||||||
dragBar: true,
|
dragBar: true,
|
||||||
showClose: false,
|
showClose: false,
|
||||||
backgroundColor: FbColors.surface,
|
backgroundColor: FbColors.surface,
|
||||||
@@ -376,6 +379,14 @@ export struct FbTopBar {
|
|||||||
} else if (this.myDetail !== null) {
|
} else if (this.myDetail !== null) {
|
||||||
FbPersonSheet({
|
FbPersonSheet({
|
||||||
person: this.myDetail,
|
person: this.myDetail,
|
||||||
|
/* 🔴🔴 必须传 embedded(2026-10-18 真机踩出来的真 bug):
|
||||||
|
`FbPersonSheet` 的根节点是"铺满全屏 + 内部居中"的浮层形态
|
||||||
|
(它的设计宿主是"页面里叠遮罩 + Stack 居中",名册页就这么用)。
|
||||||
|
直接塞进 `bindSheet`(内容要自适应高度)会**测量互相打架**:
|
||||||
|
真机症状是**每次点击 sheet 都创建了、紧接着
|
||||||
|
`AceDrag: Drag gesture has been canceled` —— 起来立刻被关**,
|
||||||
|
界面上看就是"点了没反应"(极易误判成"点击没接上")。 */
|
||||||
|
embedded: true,
|
||||||
onClose: (): void => {
|
onClose: (): void => {
|
||||||
this.myDetailSheet = false;
|
this.myDetailSheet = false;
|
||||||
},
|
},
|
||||||
@@ -399,7 +410,10 @@ export struct FbTopBar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.width('100%')
|
.width('100%')
|
||||||
.constraintSize({ maxHeight: '82%' })
|
/* ⚠️ 不要给这层加 `constraintSize({maxHeight})`:
|
||||||
|
sheet 的高度由 `SheetSize.LARGE` 决定,卡片自己已有 `maxHeight:72%`;
|
||||||
|
再叠一层百分比约束只会让"高度该多高"变成三方打架
|
||||||
|
(真机症状就是浮层起来立刻被关)。 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user