思路:

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

代码:

// 窗口管理
export class WinManager {
  context?: Context // 给ability使用
  private winNames: string[] = [] // 所有子窗口的名字

  // windows窗口创建 url: 页面路径 width: 窗口的宽度 height: 窗口的高度
  async showWin(url: string, width?: number, height?: number) {
    if (url) {
      let name = `win_${util.generateRandomUUID()}` // 说人话就是生成一个随机的id
      // 创建窗口
      const win = await window.createWindow({
        name, // 窗口的名字
        windowType: window.WindowType.TYPE_DIALOG, // 窗口的类型
        ctx: this.context || getContext() // 应用上下文信息。
      })

       // 应用主窗口与子窗口存在大小限制,默认宽度范围:[320, 1920],默认高度范围:[240,             1920],单位为vp。
      // 如果有width并且width大于等于320 有height height大于等于240 就设置窗口的大小
      if (width && width >= 320 && height && height >= 240) {
        const screen = display.getDefaultDisplaySync() // 获取Display实例
        let mainWidth = vp2px(width) // 窗口大小单位要px!! 所以转一下
        let mainHeight = vp2px(height)
        // 设置窗口大小
        win.resizeAsync(mainWidth, mainHeight)
        // 设置窗口位置
        win.moveWindowToAsync((screen.width - mainWidth) / 2, (screen.height - mainHeight) / 2)
      }
      await win.showWindow() // 展示窗口
      win.setUIContent(url) // 设置地址
      this.winNames.push(name) // 将窗口的名字添加到数组中
      return name // 返回窗口的名字
    }
    return "" // 如果没有url 就返回空字符串
  }

  // name: 窗口的名字 不传默认清空所有子窗口
  async closeWin(name?: string) {
    if (name) {
      // 查找到窗口并销毁窗口
      window.findWindow(name).destroyWindow()
      this.winNames = this.winNames.filter(item => item !== name) // 从数组中删除窗口的名字
    } else {
      // 不传就认为 想关闭所有
      let index = 0
      // 循环关闭所有窗口
      while (index < this.winNames.length) {
        await window.findWindow(this.winNames[index]).destroyWindow()
        index++
      }
      this.winNames = [] // 清空数组
    }
  }
}

// 暴露类
export const winManger = new WinManager()

知识点:

1. 创建窗口window.createWindow

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

createWindow(config: Configuration): Promise<void>

参数名

类型

必填

说明

config

Configuration

创建窗口时的参数。

// 创建窗口
const win = await window.createWindow({
  name, // 窗口的名字
  windowType: window.WindowType.TYPE_DIALOG, // 窗口的类型
  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

    • resizeAsync(width: number, height: number): Promise<void>
    • 改变当前窗口大小
    • 应用主窗口与子窗口存在大小限制,默认宽度范围:[320, 1920],默认高度范围:[240, 1920],单位为vp。

参数名

类型

必填

说明

width

number

目标窗口的宽度,单位为px

height

number

目标窗口的高度,单位为px

win.resizeAsync(mainWidth, mainHeight)

3. 显示当前窗口showWindow

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

4. 移动窗口位置moveWindowToAsync

    • moveWindowToAsync(x: number, y: number): Promise<void>
    • 在2in1设备上窗口相对于屏幕移动,其他设备上窗口相对于父窗口移动。
// 设置窗口位置
win.moveWindowToAsync((screen.width - mainWidth) / 2, (screen.height - mainHeight) / 2)

5. 配置窗口内容setUIContent

    • setUIContent(path: string): Promise<void>
    • 根据当前工程中某个页面的路径为窗口加载具体页面内容,使用Promise异步回调。
win.setUIContent(url) // 要加载到窗口中的页面内容的路径

6. 查找到窗口findWindow

    • findWindow(name: string): Window
    • 查找name所对应的窗口。

参数名

类型

必填

说明

name

string

窗口的name。

const findWin = window.findWindow(name)

7. 销毁当前窗口destroyWindow

    • destroyWindow(): Promise<void>
    • 销毁当前窗口
// 查找到窗口并关闭窗口
window.findWindow(name).destroyWindow()

8. 屏幕实例Display

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

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

screen.width // 当前设备屏幕宽

screen.height // 当前设备屏幕高

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

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐