fix(harmony): ★★ 三页 AppHeader 顶栏避让硬编码 0 ⇒ 顶栏压进系统状态栏(真机实测)
设备:HUAWEI MatePad Pro(MRDI-W00),HarmonyOS NEXT,API 26,
`hdc tconn 192.168.2.87:43679`(此前一直无真机,本条挂了 5 天)。
## 症状(用户报:「左上角全屏状态下不应该显示全屏,会与顶部系统顶栏冲突」)
截图像看是状态栏压住顶栏。**实测证伪了这个读法**:像素扫描 + `uitest dumpLayout`
显示顶栏文字在 y=134..166、系统状态栏止于 y=82,**两者不重叠**。
真正被切掉的是**列表第一封邮件的标题**(y=294..319,只剩一条细线)。
⇒ 两处独立问题,第二个(窗格头 y=222..320 与列表首行 y=294..319 重叠)
**不是顶栏避让**造成的,本次未修,见下。
## 已修:AppHeader 那一半的避让确实是坏的
`EntryAbility` 早就把避让读到了(真机日志 `insets: statusBar=38.588235
navIndicator=27.764706 windowDecor=37`),`CommPage`/`MainPage` 内容层也用了
(`top: max(statusBar, windowDecor) + paneGap`)。**但 `AppHeader` 是另一个消费者,
三处都写死了 `topInsetPx: 0`**:
· `SentTab`(发件箱) MainPage.ets:1658
· `SettingsPage`(我的) SettingsPage.ets:687
· `PermissionTab`(授权) PermissionTab.ets:487
只有 `AdminUsersPage` 是对的(`topInset(this.windowInsets)`)—— 抄它。
## 为什么已有的判据没抓到(这才是关键)
`harmony-window.test.mjs` 接线⑤「每一个 @Entry 页都要消费避让」是**绿的**,
因为它的 `consumes()` 认两种形状,其中一种只要**文件里出现过**
`this.windowInsets.statusBar` 就算过 —— 而 `MainPage` 的**内容层**正好读了它。
⇒ 页面上有**两个**避让消费者,判据只问"页里有没有出现过那个字段",
于是 `AppHeader` 里那个 0 被完全放过。
新判据(判据 10)改成**逐个消费者问**:任何传给 `AppHeader` 的 `topInsetPx`
不得是字面量 0。自检要求扫到 ≥4 处,防"遍历写错 ⇒ 永远绿"。
★ 这条判据自己先犯过一次同类错并当场被抓:第一版用 `prose()`(含注释),
把**我自己写进注释里的**「原先 topInsetPx: 0」抓成了红 ——
判据在判自己的注释。改用本文件已有的 `stripped()`(其注释原话:
「判据的锚不能落在被守对象的自述上」)。红绿已验:把 SettingsPage 退回
缺陷版 ⇒ 红;恢复 ⇒ 绿。
## 编译期抓到的一个坑
`MainPage.ets:1658` 的 AppHeader 在 **`SentTab`** 里,而 `windowInsets` 原本
只声明在 `CommPage` 上。ArkTS 报 `Property 'windowInsets' does not exist on
type 'SentTab'`。⇒ `@StorageLink` 是**每个组件各自**订阅 `AppStorage` 的,
父组件的不会自动传给子组件;直接各自订阅同一把键(比"父传子"少一层)。
## 真机验证
装机后重跑 dumpLayout:发件箱顶栏 `y=134..166`(状态栏底 y=82,间隙 52px),
截图确认「发件箱」完整显示、不再被压。
## 未修(诚实登记)
列表第一行标题被窗格头盖住(`List` 首项 y=294..319 落在窗格头 y=222..320 内),
与顶栏避让**无关**,本次未动。根因待查:`MailRow` 是 `.height(64)` 定高,
而 List 容器从 y=320 起算,首项被画到容器上方。
This commit is contained in:
@ -33,6 +33,7 @@ import { emptyTitle, emptyHint } from '../model/CommTabs';
|
||||
import { LengthMetrics } from '@kit.ArkUI';
|
||||
import { MailLike, PermissionGroup, groupPermissions, shortTimeOf } from '../model/MailGrouping';
|
||||
import { INBOX_PAGE_SIZE } from '../common/MailStore';
|
||||
import { Insets, KEY_WINDOW_INSETS, topInset } from '../model/WindowInsets';
|
||||
|
||||
/** WebUI 邮件列表统一使用 MM/DD HH:mm(与 `MainPage` 的同名函数一致)。 */
|
||||
function compactMailTime(iso: string): string {
|
||||
@ -75,6 +76,13 @@ export struct PermissionTab {
|
||||
* 对齐 WebUI `PermissionList.tsx:81` 的 `pick()` = `selectMail + showDetail`。
|
||||
*/
|
||||
onOpenMail: (mailId: string, accountId: string) => void = (): void => {};
|
||||
/*
|
||||
* 状态栏避让(窗口级事实,见 `model/WindowInsets.ts`)。
|
||||
* ★ 原先 `AppHeader({ topInsetPx: 0 })` 硬编码 0 ⇒ 授权页顶栏压进系统状态栏
|
||||
* (真机 MatePad Pro 实测 statusBar=38.58 读到了却被丢掉)。
|
||||
*/
|
||||
@StorageLink(KEY_WINDOW_INSETS) windowInsets: Insets = new Insets();
|
||||
|
||||
@State requests: PermissionRequest[] = [];
|
||||
/**
|
||||
* 已决策的**历史**,按会话分组(对齐 WebUI `PermissionList.tsx:182` 的「历史 {n}」)。
|
||||
@ -476,7 +484,7 @@ export struct PermissionTab {
|
||||
title: '授权',
|
||||
showBack: false,
|
||||
active: this.bgActive,
|
||||
topInsetPx: 0
|
||||
topInsetPx: topInset(this.windowInsets)
|
||||
}) {
|
||||
this.PendingTrailing()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user