鸿蒙中封装一个用于管理window窗口的类

79 阅读5分钟

鸿蒙中封装一个用于管理window窗口的类

思路:

  1. 创建一个名为WinManager的类。
  2. 窗口可能创建多个,定义一个名为winNames的数组用来存储所有窗口的name,方便后续删除操作
  3. 创建窗口需要用到context,那就写一个,接受外部传过来的上下文,也可以不传,没有就在当前环境中获取上下文
  4. 封装一个名为showWin的方法用来创建窗口
  5. 定义形参:窗口显示路径地址、窗口宽、高(不能小于320/240) 默认撑满(可选)
  6. 创建窗口-> (有宽高->设置宽高->居中) ->显示窗口->设置窗口地址->存到数组中->返回名字用于牛马们以后删除用
  7. 封装一个名为closeWin的方法用来销毁窗口
  8. 定义形参:用于接受销毁组件用的window的naem属性,不传默认全删
  9. 有name:找到当前窗口干掉它,并删除winNames中对应的项
  10. 没有name:干掉所有窗口,清空winNames

代码:

  1. export class WinManager {

  2. context?: Context // 给ability使用

  3. private winNames: string[] = [] // 所有子窗口的名字

  4. // windows窗口创建 url: 页面路径 width: 窗口的宽度 height: 窗口的高度

  5. async showWin(url: string, width?: number, height?: number) {

  6. let name = `win_${util.generateRandomUUID()}` // 说人话就是生成一个随机的id

  7. const win = await window.createWindow({

  8. windowType: window.WindowType.TYPE_DIALOG, // 窗口的类型

  9. ctx: this.context || getContext() // 应用上下文信息。

  10. // 应用主窗口与子窗口存在大小限制,默认宽度范围:[320, 1920],默认高度范围:[240, 1920],单位为vp。

  11. // 如果有width并且width大于等于320 有height height大于等于240 就设置窗口的大小

  12. if (width && width >= 320 && height && height >= 240) {

  13. const screen = display.getDefaultDisplaySync() // 获取Display实例

  14. let mainWidth = vp2px(width) // 窗口大小单位要px!! 所以转一下

  15. let mainHeight = vp2px(height)

  16. win.resizeAsync(mainWidth, mainHeight)

  17. win.moveWindowToAsync((screen.width - mainWidth) / 2, (screen.height - mainHeight) / 2)

  18. await win.showWindow() // 展示窗口

  19. win.setUIContent(url) // 设置地址

  20. this.winNames.push(name) // 将窗口的名字添加到数组中

  21. return name // 返回窗口的名字

  22. return "" // 如果没有url 就返回空字符串

  23. // name: 窗口的名字 不传默认清空所有子窗口

  24. async closeWin(name?: string) {

  25. window.findWindow(name).destroyWindow()

  26. this.winNames = this.winNames.filter(item => item !== name) // 从数组中删除窗口的名字

  27. while (index < this.winNames.length) {

  28. await window.findWindow(this.winNames[index]).destroyWindow()

  29. this.winNames = [] // 清空数组

  30. export const winManger = new WinManager()

知识点:

1. 创建窗口window.createWindow

创建子窗口或者系统窗口,返回一个promise对象。

createWindow(config: Configuration): Promise

  1. const win = await window.createWindow({

  2. windowType: window.WindowType.TYPE_DIALOG, // 窗口的类型

  3. ctx: this.context || getContext() // 当前应用上下文信息。

拓展上下文模型 BaseContext 区别:

对比维度FA模型Stage模型
推出时间HarmonyOS早期版本(API 7)HarmonyOS 3.1(API 9)及之后版本
设计目标面向简单应用,强调组件隔离面向复杂应用及多设备场景,优化性能与扩展性
ArkTS引擎实例每个组件(如PageAbility)独享一个ArkTS引擎实例,内存占用高多个组件共享同一ArkTS引擎实例,内存占用更低且支持状态共享
进程隔离组件运行在独立进程中主进程统一管理,支持多线程但限制自定义进程
配置文件使用config.json权限字段为reqPermissions使用module.json5,权限字段改为requestPermissions,模块化声明更清晰
组件类型分为PageAbility、ServiceAbility、DataAbility分为UIAbility(含界面)和ExtensionAbility(场景化服务),组件化更规范
窗口管理窗口与生命周期强耦合窗口管理(WindowStage)与UIAbility生命周期解耦,支持多窗口形态
多设备适配适配能力有限原生支持多设备统一生命周期,组件可跨设备迁移和协同
后台管理允许应用随意驻留后台严格管控后台进程,禁止随意驻留,防止恶意行为
开发方式面向过程开发,代码耦合度较高面向对象开发,代码可读性和维护性更好

2. 设置窗口大小resizeAsync

  1. resizeAsync(width: number, height: number): Promise
  2. 改变当前窗口大小
  3. 应用主窗口与子窗口存在大小限制,默认宽度范围:[320, 1920],默认高度范围:[240, 1920],单位为vp。
参数名类型必填说明
widthnumber目标窗口的宽度,单位为px
heightnumber目标窗口的高度,单位为px

win.resizeAsync(mainWidth, mainHeight)

3. 显示当前窗口showWindow

  1. showWindow(): Promise
  2. 显示当前窗口,使用Promise异步回调,仅支持系统窗口及应用子窗口,或将已显示的应用主窗口的层级提升至顶部。

await win.showWindow() // 展示窗口

4. 移动窗口位置moveWindowToAsync

  1. moveWindowToAsync(x: number, y: number): Promise

  2. 在2in1设备上窗口相对于屏幕移动,其他设备上窗口相对于父窗口移动。

  3. win.moveWindowToAsync((screen.width - mainWidth) / 2, (screen.height - mainHeight) / 2)

5. 配置窗口内容setUIContent

  1. setUIContent(path: string): Promise
  2. 根据当前工程中某个页面的路径为窗口加载具体页面内容,使用Promise异步回调。

win.setUIContent(url) // 要加载到窗口中的页面内容的路径

6. 查找到窗口findWindow

  1. findWindow(name: string): Window
  2. 查找name所对应的窗口。
参数名类型必填说明
namestring窗口的name。

const findWin = window.findWindow(name)

7. 销毁当前窗口destroyWindow

  1. destroyWindow(): Promise

  2. 销毁当前窗口

  3. window.findWindow(name).destroyWindow()

8. 屏幕实例Display

getAllDisplays()getDefaultDisplaySync()都是获取display实例(当前设备屏幕的信息)

  1. const screen = display.getDefaultDisplaySync() // 获取Display实例

详细用法同志们就去官网查吧