HarmonyOS 鸿蒙Next中获取避让的高度

HarmonyOS 鸿蒙Next中获取避让的高度

在EntryAbility.ets页面中引入

import { window } from '@kit.ArkUI';

并且onWindowStageCreate函数中配置一下

/** 获取底部导航栏高度 */
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);

/** 监听避让区域的变化 */
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);
  }
})

在Index.ets中配置如下

//获取顶部状态栏高度
@StorageProp('bottomRectHeight') bottomRectHeight: number = 0;
@StorageProp('topRectHeight') topRectHeight: number = 0;

async onPageShow() {
  console.log('mylog-->:', 'onPageShow bottomRectHeight: ', this.bottomRectHeight)
  console.log('mylog-->:', 'onPageShow bottomRectHeight: ', this.topRectHeight)
}

打印出打印bottomRectHeight,和topRectHeight都是打印出0啊,如何正确获取呢


更多关于HarmonyOS 鸿蒙Next中获取避让的高度的实战教程也可以访问 https://www.itying.com/category-93-b0.html

3 回复

封装全局常量 GlobalVariables.ets

export class GlobalVariables {
  /** 顶部安全区高度的key */
  static readonly SAFE_AREA_TOP_HEIGHT_KEY: string = 'safe_area_top_height'
  /** 底部安全区高度的key */
  static readonly SAFE_AREA_BOTTOM_HEIGHT_KEY: string = 'safe_area_bottom_height'
}

封装屏幕管理工具类 ScreenManager.ets

import { window } from "@kit.ArkUI"
import { GlobalVariables } from "../constants"
import { deviceInfo } from "@kit.BasicServicesKit"

class ScreenManager {
  // 开启全屏模式
  async setWindowLayoutFullScreen(context?: Context) {
    // 2in1设备的处理
    // 2in1 全屏不处理 电脑设备不处理
    if (deviceInfo.deviceType !== '2in1') {
      const win = await window.getLastWindow(context || getContext()) // 获取当前窗口
      win.setWindowLayoutFullScreen(true) // 设置为全屏

      // 设置顶部高度 把查询到的区域信息存储到AppStorage中
      AppStorage.setOrCreate(GlobalVariables.SAFE_AREA_TOP_HEIGHT_KEY,
        px2vp(win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)
      )

      // 设置底部高度 把查询到的区域信息存储到AppStorage中
      AppStorage.setOrCreate(GlobalVariables.SAFE_AREA_BOTTOM_HEIGHT_KEY,
        px2vp(win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height))
    }
  }

  // 关闭全屏模式
  async setWindowLayoutNotFullScreen(context?: Context) {
    const win = await window.getLastWindow(context || getContext()) // 获取当前窗口
    win.setWindowLayoutFullScreen(false) // 设置为非全屏
  }
}

export const screenManager = new ScreenManager()

使用示例:

onWindowStageCreate(windowStage: window.WindowStage): void {
  // ...
  screenManager.setWindowLayoutFullScreen(this.context) // 在 onWindowStageCreate 里调用 screenManager 中的 setWindowLayoutFullScreen 方法,实现顶、底安全高度的初始化
  // ...
}

页面中使用:

@Entry
@Component
struct Index {
  // 顶部安全区域
  @StorageProp(GlobalVariables.SAFE_AREA_TOP_HEIGHT_KEY)
  safeTop: number = 0
  
  build() {
    Column() {

    }
    .width('100%')
    .height('100%')
    .padding({ top:this.safeTop })
  }
}

更多关于HarmonyOS 鸿蒙Next中获取避让的高度的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在鸿蒙Next中获取避让高度需要使用避让区域管理模块。通过AvoidAreaManager类可监听系统避让区域变化,获取当前避让区域信息。主要步骤:

  1. 导入@ohos.avoidAreaManager模块
  2. 注册避让区域变化监听AvoidAreaManager.on(type, callback)
  3. 在回调中获取避让区域对象,包含typerects属性
  4. rects数组中的每个对象包含topbottom等位置信息,其中top即为顶部避让高度

关键代码示例:

import avoidAreaManager from '@ohos.avoidAreaManager'

avoidAreaManager.on('avoidAreaChange', (avoidArea) => {
  let topHeight = avoidArea.avoidAreas[0].top
})

在HarmonyOS Next中获取避让区域高度时,需要注意以下几点:

  1. 确保windowClass是有效的Window对象实例。通常在EntryAbility中应该这样获取:
let windowClass = window.getLastWindow(this.context);
  1. 需要在WindowStage创建完成后才能获取有效的避让区域数据。建议将获取代码放在onWindowStageCreate的setUIContent之后:
onWindowStageCreate(windowStage: Window.WindowStage) {
  windowStage.loadContent('pages/Index', (err) => {
    if (err) return;
    
    let windowClass = windowStage.getMainWindow();
    // 这里获取避让区域高度
  });
}
  1. 确保设备确实存在这些避让区域。模拟器或某些设备可能没有导航栏或状态栏。

  2. 打印时机问题,AppStorage的更新是异步的,建议在Index页面的aboutToAppear生命周期中获取:

aboutToAppear() {
  this.bottomRectHeight = AppStorage.get('bottomRectHeight');
  this.topRectHeight = AppStorage.get('topRectHeight');
  console.log('实际高度:', this.bottomRectHeight, this.topRectHeight);
}

如果仍获取不到,可以尝试直接使用window.getWindowAvoidArea()而不经过AppStorage中转,确认是否是存储环节的问题。

回到顶部