《HarmonyOS Next 屏幕适配:获取设备屏幕宽高数据》

前言

在鸿蒙应用开发中,屏幕适配是一个非常重要的环节。不同设备具有不同的屏幕尺寸和分辨率,为了确保应用在各种设备上都能获得良好的显示效果,我们需要获取设备的屏幕信息并进行适配。本文将详细介绍如何在鸿蒙ArkTS中获取设备的屏幕宽高数据,并实现一个可复用的屏幕适配工具类。

图1:普通手机模拟器的尺寸

图2:折叠屏手机模拟器的尺寸
图1、图2:不同尺寸的显示器对比,展示了彼此的屏幕尺寸差异

一、实现原理

1.1 核心API介绍

鸿蒙系统提供了两个重要的API来获取屏幕信息:

  • @ohos.window:提供窗口管理相关功能
  • @ohos.display:提供显示设备信息相关功能

1.2 数据存储方案

为了在应用的不同组件中都能方便地访问屏幕信息,我们采用以下存储方案:

二、代码实现

2.1 屏幕适配工具类

import window from '@ohos.window';
import display from '@ohos.display';

export class ScreenAdapter {
  // 当前屏幕宽度(单位:vp)
  private static screenWidth: number = 0;
  // 当前屏幕高度(单位:vp)
  private static screenHeight: number = 0;

  /**
   * 初始化屏幕适配
   * @param windowStage 窗口对象
   */
  static init(windowStage: window.WindowStage) {
    try {
      const win = windowStage.getMainWindowSync();
      const displayInfo = display.getDefaultDisplaySync();

      // 获取屏幕信息,转化单位为vp
      ScreenAdapter.screenWidth = px2vp(displayInfo.width);
      ScreenAdapter.screenHeight = px2vp(displayInfo.height);

      // 存储屏幕信息到AppStorage
      AppStorage.setOrCreate('screenWidth', ScreenAdapter.screenWidth);
      AppStorage.setOrCreate('screenHeight', ScreenAdapter.screenHeight);

      PersistentStorage.persistProp('screenWidth', ScreenAdapter.screenWidth);
      PersistentStorage.persistProp('screenHeight', ScreenAdapter.screenHeight);
    } catch (error) {
      console.error('屏幕适配初始化失败:', error);
    }
  }

  /**
   * 获取屏幕宽度
   * @returns 屏幕宽度
   */
  static getScreenWidth(): number {
    return ScreenAdapter.screenWidth;
  }

  /**
   * 获取屏幕高度
   * @returns 屏幕高度
   */
  static getScreenHeight(): number {
    return ScreenAdapter.screenHeight;
  }
}

提示:displayInfo 对象包含丰富的屏幕信息,可以通过以下代码查看完整信息:

console.info(JSON.stringify(displayInfo))

输出示例:

{
"id": 0,
"name": "UNKNOWN",
"alive": true,
"state": 0,
"refreshRate": 60,
"rotation": 0,
"width": 1260,
"height": 2720,
"densityDPI": 520,
"orientation": 0,
"densityPixels": 3.25,
"scaledDensity": 3.25,
"xDPI": 444.5,
"yDPI": 442.8710021972656,
"colorSpaces": [],
"hdrFormats": [],
"availableWidth": 1260,
"availableHeight": 2720
}

2.2 在EntryAbility中初始化

import window from '@ohos.window';
import { ScreenAdapter } from './ScreenAdapter';

export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage): void {
    // 初始化屏幕适配
    ScreenAdapter.init(windowStage);
    
    // 加载主页面
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        console.error('Failed to load the content. Cause: ' + JSON.stringify(err));
        return;
      }
      console.info('Succeeded in loading the content.');
    });
  }
}

三、使用示例

3.1 在页面中获取屏幕信息

import { ScreenAdapter } from '../utils/ScreenAdapter';

@Entry
@Component
struct Index {
  @StorageProp('screenWidth') screenWidth: number = 0;
  @StorageProp('screenHeight') screenHeight: number = 0;

  build() {
    Column() {
      Text(`屏幕宽度:${this.screenWidth}vp`)
        .fontSize(20)
        .margin(10)
      Text(`屏幕高度:${this.screenHeight}vp`)
        .fontSize(20)
        .margin(10)
      Text(`屏幕宽度:${vp2px(this.screenWidth)}px`)
        .fontSize(20)
        .margin(10)
      Text(`屏幕高度:${vp2px(this.screenHeight)}px`)
        .fontSize(20)
        .margin(10)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}

图3:屏幕信息显示效果
图3:屏幕信息显示效果,展示了在应用中显示屏幕宽高信息的效果

3.2 响应式布局示例

@Entry
@Component
struct ResponsiveLayout {
  build() {
    Column() {
      // 根据屏幕宽度自适应布局
      Row() {
        Text('左侧内容')
          .width(this.screenWidth * 0.3)
        Text('右侧内容')
          .width(this.screenWidth * 0.7)
      }
      .width('100%')
      .height(this.screenHeight * 0.5)
    }
  }
}

四、最佳实践

4.1 单位换算

在鸿蒙开发中,我们通常使用以下单位:

  • vp(Viewport Pixel):虚拟像素,会根据屏幕密度自动适配
  • px(Pixel):物理像素,与设备实际像素一一对应

建议在开发中优先使用vp单位,这样可以自动适配不同密度的屏幕。

4.2 错误处理

在获取屏幕信息时,需要注意以下几点:

  1. 使用try-catch捕获可能的异常
  2. 提供默认值,避免空值导致应用崩溃
  3. 在关键操作处添加日志,方便调试

4.3 性能优化

  1. 避免频繁获取屏幕信息,建议在初始化时获取并缓存
  2. 使用AppStorage实现数据共享,减少重复计算
  3. 合理使用PersistentStorage,避免过度持久化

五、常见问题

5.1 屏幕旋转处理

当设备发生旋转时,需要重新获取屏幕信息:

onWindowStageChange(windowStage: window.WindowStage) {
  // 重新初始化屏幕适配
  ScreenAdapter.init(windowStage);
}

5.2 多屏适配

对于支持多屏显示的场景,需要获取特定屏幕的信息:

const displays = display.getAllDisplays();
displays.forEach((displayInfo) => {
  // 处理每个屏幕的信息
});

六、总结

本文详细介绍了在鸿蒙ArkTS中获取设备屏幕宽高数据的方法,并提供了一个完整的屏幕适配解决方案。通过使用ScreenAdapter工具类,我们可以:

  1. 统一管理屏幕信息
  2. 实现响应式布局
  3. 适配不同设备
  4. 优化应用性能

希望本文对您的鸿蒙应用开发有所帮助。如果您有任何问题或建议,欢迎在评论区留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Albus#0_0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值