在鸿蒙HarmonyOS的 Stage 模型中窗口管理是应用 UI 呈现的核心。WindowStage是应用主窗口的容器负责管理窗口的生命周期和 UI 页面的加载。以下是关于 WindowStage 获取与窗口属性设置的基础实战一、 WindowStage 的获取方式在应用开发中获取WindowStage实例主要有两种场景和方式1. 在 UIAbility 生命周期中获取推荐在UIAbility的onWindowStageCreate回调中系统会直接传入windowStage实例。这是最标准、最安全的获取方式通常用于加载首页和监听窗口生命周期事件。import { UIAbility } from kit.AbilityKit; import { window } from kit.ArkUI; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage): void { // 1. 加载主页面 windowStage.loadContent(pages/Index, (err) { if (err.code) { console.error(加载页面失败:, err); return; } }); // 2. 订阅窗口生命周期事件如前后台切换、获焦/失焦 windowStage.on(windowStageEvent, (data: window.WindowStageEventType) { switch (data) { case window.WindowStageEventType.SHOWN: console.info(窗口进入前台); break; case window.WindowStageEventType.HIDDEN: console.info(窗口进入后台); break; } }); } }2. 在 Page 页面中获取跨组件传递如果需要在具体的 ArkUI 页面如Index.ets中获取WindowStage例如为了创建子窗口可以通过AppStorage进行跨组件传递或者通过UIAbilityContext获取。// 在 Ability 中存入 AppStorage onWindowStageCreate(windowStage: window.WindowStage): void { AppStorage.setOrCreate(windowStage, windowStage); windowStage.loadContent(pages/Index); } // 在 Page 中获取 Entry Component struct Index { aboutToAppear() { let windowStage AppStorage.getwindow.WindowStage(windowStage); // 或者通过 Context 获取 // let context getContext(this) as common.UIAbilityContext; // let ws context.windowStage; } }二、 获取主窗口并设置属性WindowStage是窗口管理器要修改窗口的具体属性如全屏、沉浸式、透明度等需要先通过它获取主窗口Main Window对象。onWindowStageCreate(windowStage: window.WindowStage): void { // 获取主窗口实例 windowStage.getMainWindow((err, mainWindow) { if (err.code) { console.error(获取主窗口失败:, err); return; } // 设置窗口属性例如全屏显示 mainWindow.setWindowLayoutFullScreen(true, (err) { if (err.code) { console.error(设置全屏失败:, err); } }); }); }三、 自由窗口尺寸限制配置对于支持自由窗口模式的设备如平板、PC开发者可以通过配置文件限制窗口的大小范围防止布局因过度拉伸而错乱。在module.json5的abilities标签中进行配置{ module: { abilities: [ { name: EntryAbility, minWindowWidth: 320, // 最小宽度 (vp) minWindowHeight: 240, // 最小高度 (vp) maxWindowWidth: 1440, // 最大宽度 (vp) maxWindowHeight: 900, // 最大高度 (vp) minWindowRatio: 0.5, // 最小宽高比 maxWindowRatio: 2 // 最大宽高比 } ] } }四、 子窗口SubWindow的创建与管理除了主窗口应用还可以通过WindowStage创建子窗口常用于实现弹窗、悬浮窗或辅助面板。子窗口的生命周期依附于主窗口。// 在 WindowStage 中创建子窗口 windowStage.createSubWindow(mySubWindow, (err, subWindow) { if (err.code) { console.error(创建子窗口失败:, err); return; } // 设置子窗口位置和大小 subWindow.moveWindowTo(300, 300); subWindow.resize(500, 500); // 为子窗口加载页面 subWindow.setUIContent(pages/SubPage, (err) { if (!err.code) { // 显示子窗口 subWindow.showWindow(); } }); });开发建议生命周期匹配务必在onWindowStageCreate中初始化窗口并在onWindowStageDestroy中释放窗口资源和取消事件监听避免内存泄漏。沉浸式适配开启全屏或沉浸式后需注意避开系统状态栏和导航栏的遮挡区域安全区可使用window.getLastWindow获取避开区域AvoidArea的坐标进行布局适配。响应式布局窗口大小改变时应结合 ArkUI 的栅格布局GridRow/GridCol和断点系统Breakpoint实现窗口缩放时的 UI 自适应。五、 沉浸式体验优化状态栏与导航栏定制当应用开启全屏布局setWindowLayoutFullScreen(true)后内容会延伸至状态栏和导航栏区域。为了保证视觉协调与可读性需要动态调整系统栏的样式。import { window } from kit.ArkUI; // 在获取到主窗口 windowClass 后 let sysBarProps: window.SystemBarProperties { statusBarColor: #00000000, // 状态栏背景透明 navigationBarColor: #00000000, // 导航栏背景透明 statusBarContentColor: #ffffff, // 状态栏图标/文字颜色白色 navigationBarContentColor: #ffffff // 导航栏图标/文字颜色 }; windowClass.setWindowSystemBarProperties(sysBarProps).then(() { console.info(系统栏样式设置成功); }).catch((err: BusinessError) { console.error(设置系统栏样式失败:, err); });六、 窗口安全与隐私保护对于包含敏感信息如密码输入、金融交易、私人聊天的页面必须防止被恶意截屏或录屏。// 开启窗口隐私模式系统级防截屏/录屏 let isPrivacyMode: boolean true; windowClass.setWindowPrivacyMode(isPrivacyMode, (err: BusinessError) { if (err.code) { console.error(开启隐私模式失败:, err); return; } console.info(隐私模式已开启当前窗口内容受保护); });七、 窗口属性精细化控制除了全屏和尺寸鸿蒙还支持对窗口的交互行为进行细粒度控制例如禁止触摸穿透、设置窗口透明度、保持屏幕常亮等。// 1. 设置窗口是否可触摸常用于弹窗时屏蔽底层交互 windowClass.setWindowTouchable(true); // 2. 获取窗口详细属性如当前宽高、是否聚焦等 let properties windowClass.getWindowProperties(); console.info(当前窗口宽度: ${properties.windowRect.width}); console.info(窗口是否可聚焦: ${properties.focusable}); // 3. 设置窗口背景透明度实现毛玻璃或半透明悬浮效果 // 注透明度可通过 WindowProperties 或 ArkUI 的 .opacity() 结合实现八、 进阶多窗口协同与智能吸附PC/大屏场景在鸿蒙 PC 或折叠屏设备上多窗口协同是核心体验。通过监听窗口位置变化可以实现类似桌面操作系统的“磁吸”效果。import window from ohos.window; // 定义吸附阈值单位px const ADSORB_THRESHOLD 10; // 监听子窗口位置变化 subWindow.on(windowPositionChange, async (currentPos) { try { // 获取当前应用内所有窗口 const windowStage await window.getLastWindowStage(); const allWindows await windowStage.getWindows(); let finalX currentPos.x; let finalY currentPos.y; // 遍历其他窗口计算边缘距离 for (let win of allWindows) { if (win.getName() subWindow.getName()) continue; const refPos await win.getPosition(); const refSize await win.getWindowSize(); // 示例右边缘吸附左边缘 if (Math.abs(finalX currentSize.width - refPos.x) ADSORB_THRESHOLD) { finalX refPos.x - currentSize.width; } } // 如果触发了吸附强制更新位置 if (finalX ! currentPos.x || finalY ! currentPos.y) { subWindow.setPosition(finalX, finalY); } } catch (err) { console.error(窗口吸附计算失败:, err); } });建议子窗口 vs 浮层Float Layer官方建议如果仅仅是应用内的弹窗、下拉菜单或提示框优先使用 ArkUI 的控件浮层能力而不是创建独立的子窗口。子窗口的创建开销较大且在分屏/自由窗口模式下控件浮层的跟随与响应性能更优。异步操作规范所有的窗口管理 API如getMainWindow,setPosition,setWindowPrivacyMode均为异步操作返回 Promise。在复杂逻辑中务必使用async/await或.then()妥善处理避免因窗口对象未初始化完成而导致的空指针异常。资源释放对于动态创建的子窗口在页面销毁aboutToDisappear或不再需要时必须调用destroyWindow()进行销毁防止内存泄漏和僵尸窗口。九、 多设备自适应窗口感知与一屏多态在鸿蒙“一次开发多端部署”的理念下窗口适配不能仅依赖设备类型如deviceType tablet而应建立一套“窗口感知能力”。横纵向断点系统Breakpoints仅靠窗口宽度无法区分所有场景如折叠屏展开与平板分屏可能宽度相同。建议引入横纵向断点系统通过getWindowProperties()获取宽高结合on(windowSizeChange)监听尺寸变化动态输出compact、medium、expanded等布局状态。折叠屏状态感知对于折叠屏设备需监听display.getFoldStatus()或半折状态。例如在相机或视频播放场景中半折状态下需要触发特殊的上下分屏交互而在小折叠Pocket系列的外屏类方屏上需强制支持旋转。自由窗口模式Free Window在 PC/2in1 设备上应用以自由窗口运行。除了通过配置文件限制最大/最小尺寸外还需通过on(freeWindowModeChange)监听状态变化并在进入/退出自由窗口时动态调整布局或触发全屏视频播放。十、 沉浸式工程化安全区避让与动态适配开启setWindowLayoutFullScreen(true)后如果处理不当极易导致内容被刘海、状态栏或底部手势条遮挡。动态获取避让区Avoid Area严禁在代码中写死paddingTop: 24等硬编码值。必须通过getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM)动态获取状态栏和导航条的高度并存储到AppStorage中供全局页面使用。监听避让区变化当设备横竖屏切换或折叠屏形态改变时避让区高度会发生变化。需注册on(avoidAreaChange)监听器实时更新全局状态确保页面布局始终安全。组件级安全区扩展对于仅需背景图延伸但内容需避让的场景推荐使用 ArkUI 的expandSafeArea属性。它允许背景图片覆盖系统栏同时子组件自动在安全区域内布局无需手动计算 padding。十一、 复杂交互架构主/子窗口协同与事件总线在 PC 或平板的多窗口协同场景下窗口间的通信和状态同步是核心难点。主/子窗口焦点联动通过on(windowEvent)监听窗口的获焦值为2与失焦值为3状态。例如当主窗口获焦时自动调用minimize()隐藏子窗口主窗口失焦时再调用showWindow()恢复子窗口实现类似桌面软件的交互体验。跨窗口通信机制子窗口通常运行在独立的 UI 上下文中。建议结合AppStorage或EventHub建立全局事件总线实现主窗口与子窗口之间的数据共享与状态同步避免复杂的回调嵌套。启动参数精细化控制在拉起新窗口时利用StartOptions进行精细化控制。例如通过withAnimation: false关闭启动动画以提升响应速度通过windowLeft/Top/Width/Height精确指定窗口初始位置和大小甚至可以通过startupVisibility: INVISIBLE实现后台静默启动待条件满足后再显示界面。