文档管理中心
|

HarmonyOS 6

HarmonyOS 5

应用从悬浮窗小窗口形态转换至悬浮窗正常态时顶部控制条遮挡

应用悬浮窗小窗口形态下,点击小窗口,使应用窗口从悬浮窗小窗口形态转换至悬浮窗正常态时,顶部控制条遮挡,全屏窗口模式与悬浮窗模式间进行切换则不会出现该情况。 &&KNOWLEDGEIMGURLPREFIX&&/20251016/37195066-cb5b-4f75-9cef-622e58e0eaaf.gif

点赞
收藏
回复
1
分享
举报
浏览115 发布于2025-10-22 12:55未知归属地
全部评论
最多点赞
最新发布
最早发布

【背景知识】

【问题定位】

  1. 查看EntryAbility.ets文件中,应用是如何动态监听并更新避让区域的变更的,发现应用采用on('windowSizeChange')或on('windowStatusChange')接口进行监听,而非采用on('avoidAreaChange')接口。

    windowClass.on('windowSizeChange',(size) => {
    
      let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
      let avoidArea = windowClass.getWindowAvoidArea(type);
      AppStorage.setOrCreate('avoidArea',avoidArea);
    
      let bottomRectHeight = avoidArea.bottomRect.height;
      AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
    
      type = window.AvoidAreaType.TYPE_SYSTEM;
      avoidArea = windowClass.getWindowAvoidArea(type);
      AppStorage.setOrCreate('avoidArea',avoidArea);
    
      let topRectHeight = avoidArea.topRect.height;
      AppStorage.setOrCreate('topRectHeight', topRectHeight);
    })
    
    windowClass.on('windowStatusChange', (WindowStatusType) => {
    
      let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR;
      let avoidArea = windowClass.getWindowAvoidArea(type);
      AppStorage.setOrCreate('avoidArea',avoidArea);
    
      let bottomRectHeight = avoidArea.bottomRect.height;
      AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
    
      type = window.AvoidAreaType.TYPE_SYSTEM;
      avoidArea = windowClass.getWindowAvoidArea(type);
      AppStorage.setOrCreate('avoidArea',avoidArea);
    
      let topRectHeight = avoidArea.topRect.height;
      AppStorage.setOrCreate('topRectHeight', topRectHeight);
    });
    
  2. 查看两种监听接口在应用窗口从悬浮窗小窗口形态转换至悬浮窗正常态时的日志输出情况,对比全屏窗口模式与悬浮窗模式间进行切换时,从悬浮窗小窗模式变为默认悬浮窗大小(包括悬浮窗状态下改变窗口尺寸)不会触发on('windowSizeChange')或on('windowStatusChange')接口进行监听。

    windowClass.on('windowSizeChange',(size) => {
      // To do sth.
    
      console.info('成功更新避让区高度变化:Succeeded in refresh the avoid area changes.');
      console.info('成功监听窗口尺寸变化:Succeeded in enabling the listener for window size changes.');
    
    })
    windowClass.on('windowStatusChange', (WindowStatusType) => {
      // To do sth.
    
      console.info('成功监听窗口模式变化:Succeeded in enabling the listener for window status changes.');
    });
    

【分析结论】

应用采用on('windowSizeChange')或on('windowStatusChange')接口进行监听并更新避让区高度,而非采用on('avoidAreaChange')接口,由于从悬浮窗小窗模式变为默认悬浮窗大小(包括悬浮窗状态下改变窗口尺寸)不会触发on('windowSizeChange')或on('windowStatusChange')接口进行监听,所以不会触发避让区高度更新,因此应用窗口从悬浮窗小窗口形态转换至悬浮窗正常态时,顶部控制条遮挡。

【修改建议】

建议采用on('avoidAreaChange')接口开启当前应用窗口系统规避区变化的监听,以实现动态监听避让区域的变更信息,页面布局根据避让区域信息进行动态调整。

windowClass.on('avoidAreaChange', (data) => {
  if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
    let topRectHeight = data.area.topRect.height;
    AppStorage.setOrCreate('topRectHeight', topRectHeight);

  } else if (data.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
    let bottomRectHeight = data.area.bottomRect.height;
    AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
    
  }
});

完整代码如下:

// EntryAbility.ets
import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onCreate');
  }

  onDestroy(): void {
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onDestroy');
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    // Main window is created,set main page for this ability
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err));
        return;
      }
      hilog.info(DOMAIN, 'testTag', 'Succeeded in loading the content.');
    });

    let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
    // 1.设置窗口全屏
    let isLayoutFullScreen = true;
    windowClass.setWindowLayoutFullScreen(isLayoutFullScreen).then(() => {
      console.info('Succeeded in setting the window layout to full-screen mode.');
    }).catch((err: BusinessError) => {
      console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`);
    });

    // 2.获取布局避让遮挡的区域
    let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 此处以导航条避让为例
    let avoidArea = windowClass.getWindowAvoidArea(type);
    let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航区域的高度
    AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);


    type = window.AvoidAreaType.TYPE_SYSTEM; // 以状态栏避让为例
    avoidArea = windowClass.getWindowAvoidArea(type);
    let topRectHeight = avoidArea.topRect.height; // 获取状态栏区域高度
    AppStorage.setOrCreate('topRectHeight', topRectHeight);

    // 3.注册监听函数,动态获取避让区域数据
    windowClass.on('avoidAreaChange', (data) => {
      if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
        let topRectHeight = data.area.topRect.height;
        AppStorage.setOrCreate('topRectHeight', topRectHeight);

      } else if (data.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
        let bottomRectHeight = data.area.bottomRect.height;
        AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);

      }
    });

  }

  onWindowStageDestroy(): void {
    // Main window is destroyed,release UI related resources
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  }

  onForeground(): void {
    // Ability has brought to foreground
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onForeground');
  }

  onBackground(): void {
    // Ability has back to background
    hilog.info(DOMAIN, 'testTag', '%{public}s', 'Ability onBackground');
  }
}
// Index.ets
@Entry
@Component
struct Index {
  @StorageProp('bottomRectHeight')
  bottomRectHeight: number = 0;
  @StorageProp('topRectHeight')
  topRectHeight: number = 0;

  build() {
    Column() {
      Row() {
        Text('Top Content').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }.backgroundColor('#2786d9')

      Row() {
        Text('Display Content 2').fontSize(30)
      }.backgroundColor(Color.White).padding(20).borderRadius(15).width('80%')

      Row() {
        Text('Display Content 3').fontSize(30)
      }.backgroundColor(Color.White).padding(20).borderRadius(15).width('80%')

      Row() {
        Text('Display Content 4').fontSize(30)
      }.backgroundColor(Color.White).padding(20).borderRadius(15).width('80%')

      Row() {
        Text('Display Content 5').fontSize(30)
      }.backgroundColor(Color.White).padding(20).borderRadius(15).width('80%')

      Row() {
        Text('Bottom Content').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }.backgroundColor('#96dffa')
    }
    .width('100%').height('100%')
    .alignItems(HorizontalAlign.Center)
    .backgroundColor('#d5d5d5')
    .justifyContent(FlexAlign.SpaceBetween)
    // top数值与状态栏区域高度保持一致;bottom数值与导航区域高度保持一致
    .padding({
      top: this.getUIContext().px2vp(this.topRectHeight),
      bottom: this.getUIContext().px2vp(this.bottomRectHeight)
    })
  }
}
展开全部
1楼回复于2025-10-22 12:55 未知归属地
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要提问题

了解社区公约,与您携手共创和谐专业的开发者社区。