已开启
按沉浸式布局动态计算状态栏 padding,修复证书管理/安装页被遮挡问题,UIAbility拉起页面时,通过读 isLayoutFullScreen判断当前窗口是否为沉浸式,进而调整padding的取值 #104
按沉浸式布局动态计算状态栏 padding,修复证书管理/安装页被遮挡问题,UIAbility拉起页面时,通过读 isLayoutFullScreen判断当前窗口是否为沉浸式,进而调整padding的取值 #104
已开启
hyl创建于 7月25日
3 个文件变更+119-5
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright (c) 2026 Huawei Device Co., Ltd.
3+ * Licensed under the Apache License, Version 2.0 (the "License");
4+ * you may not use this file except in compliance with the License.
5+ * You may obtain a copy of the License at
6+ *
7+ * http://www.apache.org/licenses/LICENSE-2.0
8+ *
9+ * Unless required by applicable law or agreed to in writing, software
10+ * distributed under the License is distributed on an "AS IS" BASIS,
11+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+ * See the License for the specific language governing permissions and
13+ * limitations under the License.
14+ */
15+ 
16+import { window } from '@kit.ArkUI';
17+import { BusinessError } from '@ohos.base';
18+import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
19+import hilog from '@ohos.hilog';
20+import { GlobalContext } from '../GlobalContext';
21+ 
22+const DOMAIN = 0x0000;
23+const TAG = 'StatusBarPaddingUtil';
24+ 
25+function hilogInfo(message: string): void {
26+ hilog.info(DOMAIN, TAG, message);
27+}
28+ 
29+function hilogError(message: string): void {
30+ hilog.error(DOMAIN, TAG, message);
31+}
32+ 
33+/**
34+ * Determines whether manual status bar padding is required when opening a page:
35+ * UIExtension uses host position; UIAbility uses isLayoutFullScreen.
36+ */
37+export function updateStatusBarPaddingByImmersive(context: Context,
38+ onResult: (topPadding: number) => void): void {
39+ try {
40+ const session = GlobalContext.getContext().getSession();
41+ if (session !== undefined && session !== null) {
42+ onResult(resolveUiExtensionStatusBarPadding(session));
43+ return;
44+ }
45+ resolveUiAbilityStatusBarPadding(context, onResult);
46+ } catch (error) {
47+ const err: BusinessError = error as BusinessError;
48+ hilogError(`updateStatusBarPaddingByImmersive error: ${err.code}, ${err.message}`);
49+ const cached: number | undefined = AppStorage.get('STATUS_BAR_HEIGHT') as number | undefined;
50+ onResult(cached !== undefined ? cached : 0);
51+ }
52+}
53+ 
54+/**
55+ * UIExtension scenario: determine whether manual status bar padding is required based on host position.
56+ */
57+function resolveUiExtensionStatusBarPadding(session: UIExtensionContentSession): number {
58+ const extensionWindow = session.getUIExtensionWindowProxy();
59+ const area: window.AvoidArea =
60+ extensionWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);
61+ const barHeight: number = px2vp(area.topRect.height);
62+ let needPadding: boolean = true;
63+ 
64+ const hostRect: window.Rect = extensionWindow.properties.uiExtensionHostWindowProxyRect;
65+ if (hostRect !== undefined && hostRect !== null) {
66+ const hostTop: number = px2vp(hostRect.top);
67+ needPadding = hostTop < barHeight - 2;
68+ hilogInfo(`hostTop=${hostTop}, barHeight=${barHeight}, needPadding=${needPadding}`);
69+ } else {
70+ hilogInfo(`hostRect unavailable, barHeight=${barHeight}`);
71+ }
72+ 
73+ const topPadding: number = needPadding ? barHeight : 0;
74+ AppStorage.setOrCreate('STATUS_BAR_HEIGHT', topPadding);
75+ return topPadding;
76+}
77+ 
78+/**
79+ * UIAbility scenario: determine whether manual status bar padding is required based on isLayoutFullScreen.
80+ */
81+function resolveUiAbilityStatusBarPadding(context: Context,
82+ onResult: (topPadding: number) => void): void {
83+ window.getLastWindow(context).then((win: window.Window) => {
84+ const isLayoutFullScreen: boolean = win.getWindowProperties().isLayoutFullScreen;
85+ const barHeight: number =
86+ px2vp(win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height);
87+ const topPadding: number = isLayoutFullScreen ? barHeight : 0;
88+ AppStorage.setOrCreate('STATUS_BAR_HEIGHT', topPadding);
89+ hilogInfo(`isLayoutFullScreen=${isLayoutFullScreen}, statusBarHeight=${topPadding}`);
90+ onResult(topPadding);
91+ }).catch((err: BusinessError) => {
92+ hilogError(`getLastWindow failed: ${err.code}, ${err.message}`);
93+ const cached: number | undefined = AppStorage.get('STATUS_BAR_HEIGHT') as number | undefined;
94+ onResult(cached !== undefined ? cached : 0);
95+ });
96+}
@@ -32,6 +32,7 @@ import { SheetParam } from '../common/util/SheetParam';
32import FilterParams from '../common/constants/FileFilterParams';32import FilterParams from '../common/constants/FileFilterParams';
33import { UIContext } from '@kit.ArkUI';33import { UIContext } from '@kit.ArkUI';
34import { common } from '@kit.AbilityKit';34import { common } from '@kit.AbilityKit';
35+import { updateStatusBarPaddingByImmersive } from '../common/util/StatusBarPaddingUtil';
35 36 
36const COPIES_NUM: number = 12;37const COPIES_NUM: number = 12;
37 38 
@@ -53,10 +54,18 @@ export struct CertInstallFromStorage {
53 @State private headRectHeightReal: number = 0;54 @State private headRectHeightReal: number = 0;
54 private scroller: Scroller = new Scroller();55 private scroller: Scroller = new Scroller();
55 @State private scrollerHeight: number = 0;56 @State private scrollerHeight: number = 0;
56- @State statusBarHeight: number = 057+ @State statusBarHeight: number = 0;
58+ 
57 aboutToAppear(): void {59 aboutToAppear(): void {
58- this.statusBarHeight = AppStorage.get('STATUS_BAR_HEIGHT') as number60+ if (this.isStartBySheet) {
61+ this.statusBarHeight = 0;
62+ return;
63+ }
64+ updateStatusBarPaddingByImmersive(this.context, (topPadding: number) => {
65+ this.statusBarHeight = topPadding;
66+ });
59 }67 }
68+ 
60 @Styles normalStyle() {69 @Styles normalStyle() {
61 .backgroundColor($r('sys.color.ohos_id_color_card_bg'))70 .backgroundColor($r('sys.color.ohos_id_color_card_bg'))
62 .borderRadius($r('app.float.user_list_divider_borderRadius_value'))71 .borderRadius($r('app.float.user_list_divider_borderRadius_value'))
@@ -387,7 +396,7 @@ export struct CertInstallFromStorage {
387 .backgroundColor($r('sys.color.ohos_id_color_sub_background'))396 .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
388 .width(WidthPercent.WH_100_100)397 .width(WidthPercent.WH_100_100)
389 .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100)398 .height(this.isStartBySheet ? WidthPercent.WH_AUTO : WidthPercent.WH_100_100)
390- .padding({top:this.statusBarHeight})399+ .padding({ top: this.statusBarHeight });
391 }400 }
392 401 
393 getScrollMinHeight() {402 getScrollMinHeight() {
@@ -23,6 +23,7 @@ import promptAction from '@ohos.promptAction';
23import { CustomContentDialog } from '@ohos.arkui.advanced.Dialog';23import { CustomContentDialog } from '@ohos.arkui.advanced.Dialog';
24import { NavEntryKey } from '../common/NavEntryKey';24import { NavEntryKey } from '../common/NavEntryKey';
25import { SheetParam } from '../common/util/SheetParam';25import { SheetParam } from '../common/util/SheetParam';
26+import { updateStatusBarPaddingByImmersive } from '../common/util/StatusBarPaddingUtil';
26 27 
27const DISPLAY_DURATION: number = 2000;28const DISPLAY_DURATION: number = 2000;
28const COPIES_NUM: number = 12;29const COPIES_NUM: number = 12;
@@ -55,10 +56,18 @@ export struct CertificateComponent {
55 @Prop sheetParam: SheetParam;56 @Prop sheetParam: SheetParam;
56 private scroller: Scroller = new Scroller();57 private scroller: Scroller = new Scroller();
57 @State private scrollerHeight: number = 0;58 @State private scrollerHeight: number = 0;
58- @State statusBarHeight: number = 059+ @State statusBarHeight: number = 0;
60+ 
59 aboutToAppear(): void {61 aboutToAppear(): void {
60- this.statusBarHeight = AppStorage.get('STATUS_BAR_HEIGHT') as number62+ if (this.isStartBySheet) {
63+ this.statusBarHeight = 0;
64+ return;
65+ }
66+ updateStatusBarPaddingByImmersive(getContext(this), (topPadding: number) => {
67+ this.statusBarHeight = topPadding;
68+ });
61 }69 }
70+ 
62 build() {71 build() {
63 Column() {72 Column() {
64 GridRow({73 GridRow({