From 1c1a85946452deb4c1eb8b0b340bafb3ee9bf224 Mon Sep 17 00:00:00 2001 From: laoyang Date: Sun, 18 Oct 2026 21:56:34 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E3=80=8C=E5=90=8D=E5=86=8C=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E5=8F=B3=E4=BE=A7=E8=B4=B4=E5=B1=8F=E5=B9=95=E3=80=8D?= =?UTF-8?q?=E7=9A=84=E7=9C=9F=E5=87=B6=EF=BC=9Awidth('100%')=20=E4=B8=8E?= =?UTF-8?q?=20margin=20=E6=89=93=E6=9E=B6=EF=BC=88=E4=B8=8D=E6=98=AF=20fle?= =?UTF-8?q?xShrink=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 真机实测纠正了我第一轮的误判。 现象(用户):「名册列表左侧有空隙了……怎么右侧不是呢?右侧还是紧贴屏幕。」 像素实测:左米色 52~72px、**右米色 0px**;布局树里卡片盒子 x = **50~1080**。 🔴 真根因:卡片**同时**写了 .width('100%') .margin({ left: 16, right: 16 }) `100%` 是相对**父容器全宽**(= 屏宽 1080),margin 再把盒子往右推 ⇒ 盒子变成 50~1080(左边留 50、右边 0)—— 正是用户看到的形态。 ⇒ 去掉 `.width('100%')`,Row 按"父宽 − margin"自适应,两边都是 16。 真机复验:卡片盒子 x = 50~**1030**(左右各 50,对称); 像素扫描 y=860/880/1090/1310 全部 **左=右**。 ⚠️ 我第一轮误判成"内容把卡片撑破",去加了 `flexShrink(1)` —— 那是**错的**: `flexShrink` 防的是"长名字把同行的小标签挤没",与本 bug 无关。 真正的证据是**布局树里卡片自己的 x 是 50~1080**(不是子节点越界)。 ⇒ 教训:**先量"卡片本身"的盒子,再怀疑子节点。** (`flexShrink` 保留 —— 它本身是有价值的防护,但注释已改正, 不再宣称它是本 bug 的修法。) 验证:hvigor BUILD SUCCESSFUL;_fb_arkts_guard.js 378/0; _fb_v59c_falsify.py 16/0(本批新增第 16 项注入:把 width('100%') 加回卡片, 必须被抓住。该判据本身也反复调了三轮才既不恒红、又能抓住注入: "别处也有" ⇒ 恒红;"取卡片尾部窗口" ⇒ 覆盖不到注入点; "取 personRow 整段" ⇒ 段里天然含 4 处 width(3 处在注释里)⇒ 基线红; 最终 = **剥注释 + 只看卡片自己那一层**)。 --- .../main/ets/pages/people/FbPeoplePage.ets | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/entry/src/main/ets/pages/people/FbPeoplePage.ets b/entry/src/main/ets/pages/people/FbPeoplePage.ets index 4aa8711..b02f28f 100644 --- a/entry/src/main/ets/pages/people/FbPeoplePage.ets +++ b/entry/src/main/ets/pages/people/FbPeoplePage.ets @@ -1035,14 +1035,10 @@ export struct FbPeoplePage { .fontColor(FbColors.ink) .fontWeight(FontWeight.Medium) .maxLines(1) - /* 🔴🔴 内容必须**允许收缩**(`flexShrink`),否则会把卡片撑破 —— - * 这就是用户 2026-10-18 报的「左侧有空隙、右侧紧贴屏幕」。 - * 原理:Row 里的子项默认 `min-width: auto`(= 按内容最小宽度), - * 长名字 / 多个标签会把这一行顶得比卡片可用宽度更宽; - * 卡片本身有 `margin(left/right: 16)`,但**布局盒被内容撑出去**, - * 于是右边越界贴到屏幕缘(左边因为 margin 先占位,所以还有空隙)。 - * ⇒ 给两个可能变长的 Row 都开 `flexShrink(1)` + 给 Text 让路。 - * (本项目第 N 次踩这个"flex 子项不收缩"的坑,见 pitfalls。) */ + /* ⚠️ 允许收缩 —— 长名字不会把这一行顶出去。 + * ⚠️ 注意:这**不是**"右侧贴屏幕"的根因(那个是卡片自己的 + * `.width('100%')` + margin 打架,见下方卡片那段的说明); + * 它防的是"长名字把同行的小标签挤没"。 */ .flexShrink(1) if (p.isAdmin) { FbTag({ text: '管理员', tone: 'brand' }) @@ -1082,7 +1078,16 @@ export struct FbPeoplePage { * 右侧撑破的元凶之一(固定宽度 + 不收缩)。 */ } - .width('100%') + /* 🔴🔴 **绝对不要在这里写 `.width('100%')`**(2026-10-18 真机实测找到的真凶): + * 卡片同时有 `.margin({left:16, right:16})` 与 `.width('100%')` 时, + * `100%` 是相对**父容器全宽**(= 屏宽 1080),margin 再把盒子往右推 + * ⇒ 实测卡片 x 范围是 `50 ~ 1080`(**左边留了 50、右边 0**), + * 正好就是用户报的「左侧有空隙、右侧紧贴屏幕」。 + * ⇒ 去掉 `width`,Row 按"父宽 − margin"自适应,两边就都是 16。 + * ⚠️ 一开始我误判成"内容把卡片撑破"(`flexShrink`),加了收缩也没用 —— + * 真正的证据是**布局树里卡片自己的 x 是 50~1080**(不是子节点越界)。 + * 教训:先量**卡片本身**的盒子,再怀疑子节点。 + */ .padding({ left: 14, right: 14, top: 12, bottom: 12 }) /* 🔴 v59b(用户 2026-10-18):「每个人都是圆角矩形,往中间收一点, * 距离左右都有点距离,每个人中间都有一点空隙。这样是很多个