引言

你的App需要知道屏幕的宽高来做自适应布局?要适配折叠屏的展开/折叠状态?要根据刷新率调整动画帧率?HarmonyOS 的 @ohos.display 模块就是干这个的。

本文涵盖屏幕信息获取、折叠状态监听、刷新率读取等核心能力。


一、基础信息获取

import display from '@ohos.display';

1.1 获取默认显示设备

const defaultDisplay = display.getDefaultDisplaySync();
console.log({
  width: defaultDisplay.width,            // 逻辑分辨率宽
  height: defaultDisplay.height,          // 逻辑分辨率高
  densityPixels: defaultDisplay.densityPixels,  // 像素密度
  densityDPI: defaultDisplay.densityDPI,        // DPI
  refreshRate: defaultDisplay.refreshRate,      // 刷新率(Hz)
  rotation: defaultDisplay.rotation,            // 旋转角度
  orientation: defaultDisplay.orientation,      // 横竖屏状态
});

1.2 实际像素 vs 逻辑像素

const d = display.getDefaultDisplaySync();
// 逻辑像素 → 物理像素
const physicalWidth = px2vp(d.width); // 反之用 vp2px
const physicalHeight = px2vp(d.height);

// 直接使用 vp 单位
console.log(`屏幕: ${d.width}x${d.height} vp, ${d.densityPixels}x 密度`);

二、折叠屏适配

2.1 判断折叠状态

// 获取折叠信息
const foldInfo = display.getDefaultDisplaySync().foldStatus;
console.log('折叠状态:', foldStatus);

// 可能的状态值
enum FoldStatus {
  UNKNOWN = 0,       // 未知
  EXPANDED = 1,      // 展开
  FOLDED = 2,        // 折叠
  HALF_FOLDED = 3    // 半折叠(悬停模式)
}

2.2 监听折叠状态变化

import { BusinessError } from '@kit.BasicServicesKit';

// 注册折叠状态变化监听
display.on('foldStatusChange', (status: display.FoldStatus) => {
  switch (status) {
    case display.FoldStatus.EXPANDED:
      console.log('设备已展开 → 切换为大屏布局');
      break;
    case display.FoldStatus.FOLDED:
      console.log('设备已折叠 → 切换为小屏布局');
      break;
    case display.FoldStatus.HALF_FOLDED:
      console.log('设备半折叠 → 进入悬停模式');
      break;
  }
});

// 组件销毁时移除
aboutToDisappear() {
  display.off('foldStatusChange');
}

三、多屏与扩展显示

3.1 获取所有显示设备

const allDisplays = display.getAllDisplays();
console.log('共有', allDisplays.length, '个屏幕');

// 每个屏幕信息
allDisplays.forEach((d, i) => {
  console.log(`屏幕${i + 1}: ${d.width}x${d.height} @${d.refreshRate}Hz`);
});

3.2 监听屏幕变化

// 屏幕连接/断开(外接显示器)
display.on('add', (d: display.Display) => {
  console.log('新屏幕接入:', d.id);
});
display.on('remove', (d: display.Display) => {
  console.log('屏幕断开:', d.id);
});

// 屏幕属性变化(分辨率/刷新率变更)
display.on('change', (d: display.Display) => {
  console.log('屏幕属性变化:', d.id, d.width, d.height);
});

四、实战:自适应布局工具

class ScreenAdaptor {
  private display: display.Display;

  constructor() {
    this.display = display.getDefaultDisplaySync();
    this.initListeners();
  }

  // 根据屏幕宽度判断设备类型
  getDeviceType(): 'phone' | 'tablet' | 'foldable' {
    const w = this.display.width;
    if (w >= 840) return 'tablet';
    if (w >= 600) return 'foldable';
    return 'phone';
  }

  // 根据刷新率决定动画帧率
  getRecommendedFrameRate(): number {
    const rate = this.display.refreshRate;
    // 120Hz 屏幕用 60fps 动画也流畅,省电
    return Math.min(rate, 60);
  }

  // 计算安全区域
  getSafeArea(): { top: number; bottom: number } {
    // 折叠屏展开时有一些区域被遮挡
    return {
      top: this.display.height * 0.02,
      bottom: this.display.height * 0.02
    };
  }

  private initListeners() {
    display.on('change', () => {
      this.display = display.getDefaultDisplaySync();
    });
  }
}

// 使用
const adaptor = new ScreenAdaptor();
console.log('设备类型:', adaptor.getDeviceType());

五、关键属性速查

属性 类型 说明
width number 显示区域宽度(vp)
height number 显示区域高度(vp)
densityPixels number 屏幕密度
densityDPI number DPI
refreshRate number 屏幕刷新率(Hz)
rotation number 旋转角度(0/90/180/270)
orientation Orientation 横竖屏状态
foldStatus FoldStatus 折叠状态
isHdr boolean 是否支持HDR
colorDepth number 色深(bit)

六、最佳实践

✅ 正确用法

// 1. 不要在 build 方法里反复 getDefaultDisplaySync
// ✅ 在 aboutToAppear 获取一次,监听变化更新
aboutToAppear() {
  this.displayInfo = display.getDefaultDisplaySync();
  display.on('change', () => {
    this.displayInfo = display.getDefaultDisplaySync();
  });
}

// 2. 折叠屏适配用 @State + foldStatusChange
@State isExpanded: boolean = true;
aboutToAppear() {
  display.on('foldStatusChange', (status) => {
    this.isExpanded = status === display.FoldStatus.EXPANDED;
  });
}

⚠️ 注意事项

  • getDefaultDisplaySync 只能在 UI 线程调用
  • 不要在循环中频繁获取:信息不会频繁变,缓存即可
  • 折叠状态变化后布局可能重新测量@State 驱动重新渲染
  • 多屏场景下默认屏幕不一定是内屏

总结

自适应布局

折叠适配

动画优化

多屏场景

getDefaultDisplaySync

用途

width/height/densityPixels

foldStatus + foldStatusChange

refreshRate

getAllDisplays + add/remove监听

@ohos.display 是你连接鸿蒙设备的"眼睛"——知道屏幕是什么样子,才能做出适配的体验。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐