《HarmonyOS技术精讲-窗口管理》第七篇:窗口事件处理与焦点管理

《HarmonyOS技术精讲-窗口管理》第七篇:窗口事件处理与焦点管理

事件响应与焦点:掌握 HarmonyOS 窗口生命周期中的关键事件监听

一、前言

在 HarmonyOS 应用开发过程中,窗口(Window)不仅仅是承载 UI 的容器,它还负责管理应用与用户之间的交互状态。

例如:

  • 用户点击不同窗口时,需要知道当前哪个窗口获得焦点;
  • 应用进入后台时,需要暂停视频播放、释放资源;
  • 应用重新显示时,需要恢复数据和刷新界面;
  • 分屏、多窗口场景下,需要根据窗口大小动态调整布局。

这些场景都依赖窗口事件监听机制。

HarmonyOS 提供了丰富的 Window 事件能力,开发者可以通过监听窗口状态变化,实现更加智能的交互体验。

本文重点介绍三个常用窗口事件:

  • focusChange:窗口焦点变化事件
  • windowVisibilityChange:窗口显示隐藏事件
  • windowSizeChange:窗口大小变化事件

二、窗口事件处理基础

在 HarmonyOS Stage 模型中,我们通常通过 WindowStage 获取当前应用窗口。

基本流程:

应用启动 → 创建 WindowStage → 获取 Window 对象 → 注册事件监听 → 响应窗口变化

示例:

ts 复制代码
import { window } from '@kit.ArkUI';
import { UIAbility } from '@kit.AbilityKit';


export default class EntryAbility extends UIAbility {

  onWindowStageCreate(windowStage: window.WindowStage) {

    windowStage.getMainWindow().then((win) => {

      console.info("窗口创建成功");

      this.registerWindowListener(win);

    });
  }


  registerWindowListener(win: window.Window) {

    console.info("开始监听窗口事件");

  }

}

获取到 window.Window 对象后,就可以监听各种窗口状态变化。


三、监听窗口焦点事件 focusChange

1. 什么是窗口焦点?

焦点代表当前窗口是否处于用户交互状态。

例如:

用户打开应用:

窗口获得焦点 → 接收用户输入 → 响应点击操作

当用户打开其他窗口:

原窗口失去焦点 → 暂停交互

在多窗口、悬浮窗场景中,焦点管理非常重要。


2. 监听焦点变化

HarmonyOS 提供 focusChange 事件监听窗口焦点状态。

ts 复制代码
win.on('focusChange', (isFocused) => {

  if (isFocused) {

    console.info("当前窗口获得焦点");

  } else {

    console.info("当前窗口失去焦点");

  }

});

参数说明:

参数 说明
true 窗口获得焦点
false 窗口失去焦点

四、实战:两个窗口焦点联动

下面实现一个实际案例:

需求:

创建两个窗口:

窗口 A:

  • 获得焦点时改变背景颜色

窗口 B:

  • 失去焦点时隐藏

实现效果:

窗口 A 获得焦点 → 更新背景

窗口 B 失去焦点 → 自动隐藏


创建窗口管理类

ts 复制代码
import { window } from '@kit.ArkUI';


export class WindowManager {


  private mainWindow?: window.Window;

  private secondWindow?: window.Window;



  async init(context) {

    this.mainWindow =
      await window.getLastWindow(context);


    this.registerMainWindowEvent();

  }



  registerMainWindowEvent() {


    this.mainWindow?.on(
      'focusChange',
      (focus)=>{


        if(focus){

          console.info(
          "主窗口获得焦点");


          this.changeBackground();

        }


      });


  }



  changeBackground(){

    console.info(
      "改变窗口背景颜色");

  }


}

第二窗口监听焦点

ts 复制代码
secondWindow.on(
'focusChange',
(focus)=>{


  if(!focus){


    console.info(
    "第二窗口失去焦点");


    secondWindow.hide();

  }


});

这种方式可以实现:

  • 悬浮聊天窗口
  • 视频小窗
  • 工具面板
  • 多窗口协同

五、监听窗口显示隐藏事件

除了焦点变化,窗口显示状态也是非常重要的生命周期事件。

例如:

用户离开页面:

窗口隐藏 → 暂停动画 → 停止定位 → 释放资源

用户返回:

窗口显示 → 恢复状态 → 加载数据

监听代码:

ts 复制代码
win.on(
'windowVisibilityChange',
(visible)=>{


  if(visible){


    console.info(
    "窗口显示");


    loadResource();


  }else{


    console.info(
    "窗口隐藏");


    releaseResource();

  }


});

实际应用场景:视频播放

窗口隐藏:

ts 复制代码
function releaseResource(){

 console.info(
 "暂停视频播放");

}

窗口显示:

ts 复制代码
function loadResource(){

 console.info(
 "恢复视频播放");

}

可以避免后台运行导致:

  • CPU 占用增加
  • 网络浪费
  • 电量消耗

六、监听窗口大小变化事件 windowSizeChange

HarmonyOS 支持多种设备形态:

  • 手机
  • 平板
  • 电脑
  • 折叠屏

窗口尺寸可能动态变化。

例如:

全屏 → 分屏 → 重新布局

监听代码:

ts 复制代码
win.on(
'windowSizeChange',
(size)=>{


 console.info(
 `窗口大小:
 ${size.width}x${size.height}`
 );


});

七、根据窗口大小动态调整布局

例如:

手机:

单列布局

平板:

左右双栏布局

代码:

ts 复制代码
win.on(
'windowSizeChange',
(size)=>{


 if(size.width < 600){


   console.info(
   "切换手机布局");


 }else{


   console.info(
   "切换平板布局");


 }


});

通过窗口尺寸变化,可以实现:

  • 自适应 UI
  • 横竖屏适配
  • 折叠屏适配

八、完整窗口事件管理示例

ts 复制代码
import {
 window
} from '@kit.ArkUI';



export class AppWindowController {


private win?:window.Window;



init(win:window.Window){


 this.win=win;


 this.bindEvent();

}



bindEvent(){


 this.win?.on(
 'focusChange',
 (focus)=>{


  if(focus){

   console.info(
   "窗口激活");


  }else{


   console.info(
   "窗口暂停交互");

  }


 });



 this.win?.on(
 'windowVisibilityChange',
 (visible)=>{


  if(visible){

    this.resume();


  }else{

    this.pause();

  }


 });



 this.win?.on(
 'windowSizeChange',
 (size)=>{


 console.info(
 "窗口尺寸变化",
 size.width,
 size.height
 );


 });


}



resume(){

 console.info(
 "恢复资源");

}



pause(){

 console.info(
 "释放资源");

}


}

九、开发注意事项

1. 及时移除监听

长期监听可能导致资源泄漏。

销毁时:

ts 复制代码
win.off(
'focusChange'
);

2. 避免事件中执行耗时任务

不要:

焦点变化 → 大量数据加载 → 页面卡顿

推荐:

焦点变化 → 异步任务 → 更新状态


3. 不要假设窗口创建后一定获得焦点

多窗口环境下:

创建窗口 ≠ 获得焦点

应该通过:

ts 复制代码
focusChange

实时判断。


十、总结

本篇学习了 HarmonyOS 窗口事件管理。

核心知识点:

focusChange

监听窗口焦点变化。

适用于:

  • 用户交互控制
  • 多窗口协同
  • 悬浮窗管理

windowVisibilityChange

监听窗口显示隐藏。

适用于:

  • 生命周期管理
  • 资源释放
  • 数据恢复

windowSizeChange

监听窗口大小变化。

适用于:

  • 分屏适配
  • 折叠屏适配
  • 多设备布局

掌握窗口事件监听后,可以让 HarmonyOS 应用在不同设备形态和复杂交互场景下保持稳定运行。


示例代码项目地址:项目地址