Skip to content

多尺寸屏幕适配

基于API12.

之前开发的时候都涉及同设计沟通,都是基于设计稿的宽度来适配的。想小程序默认都是750rpx,iOS都是pt。但是鸿蒙支持的设备宽度跨度太大,有单屏幕、折叠屏、平板、后续应该还有电脑,这样真正的能做到一次开发鸿蒙全平台部署了。看起来是提前实现了swiftUI的设计目的。

这种情况参考网页的栅格布局,鸿蒙系统提供默认的断点xs, sm, md, lg四类。这样对于之前的设计稿,如果还是按照鸿蒙提供的lpx方式来适配,直接拉伸放到折叠屏上就不太好看了,而且当旋转屏幕的时候lpx也会适配到宽度上,会导致页面直接拉伸变大,因此需要针对不同尺寸做适配。最好不使用lpx的方式,而是自己计算缩放。

断点描述

  • xs [0, 320) 最小宽度类型设备
  • sm [320, 520) 小宽度类型设备
  • md [520, 840) 中等宽度类型设备
  • lg [840, +00) 大宽度类型设备

当前按照只适配单屏和折叠屏来示例,如果还要适配平板也可以在多加一个断点来适配。断点选在了520这个宽度上,小于520认为是单屏,大于520认为是折叠屏。

获取屏幕宽度

获取屏幕的宽度,在屏幕折叠展开的时候更新屏幕宽度。但是当屏幕旋转的时候也会触发屏幕大小变化的回调,因此只有在竖屏的时候更新这个。

在 UIAbility 里边加这么一层判断,由于没有试平板,那个可能是默认是landspace,那就需要先判断一下断点,然后在期望的宽度方向上更新这个,毕竟马上就要出三折屏了。

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

export default class EntryAbility extends UIAbility {
  windowObj?: window.Window
  private updateBreakpoint() :void {
    if (this.windowObj) {
      if (this.windowObj.getPreferredOrientation() == window.Orientation.PORTRAIT) {
        let w = this.windowObj.getWindowProperties().windowRect.width
        let h = this.windowObj.getWindowProperties().windowRect.height
        let wvp = px2vp(w)
        let hvp = px2vp(h)
        AppStorage.setOrCreate('screenWidth', wvp)
        AppStorage.setOrCreate('screenHeight', hvp)

        if (wvp < 520) {
          AppStorage.setOrCreate('designWidth', 375)
        } else {
          AppStorage.setOrCreate('designWidth', 750)
        }
      }
    }
  }

  async onWindowStageCreate(windowStage: window.WindowStage) {
    this.windowObj = windowStage.getMainWindowSync()
    this.windowObj.setPreferredOrientation(window.Orientation.PORTRAIT)
    let statusHeight = this.windowObj.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height
    let bottomHeight = this.windowObj.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height
    AppStorage.setOrCreate('bottomHeight',px2vp(bottomHeight))
    AppStorage.setOrCreate('statusHeight',px2vp(statusHeight))

    this.updateBreakpoint()
    this.windowObj.on('windowSizeChange', (windowSize)=>{
      this.updateBreakpoint()
    })
  }
}

转化计算

编写一个自定义的转换函数,先计算获取到缩放比例,然后获取实际的长度。

js
export const xv = (len: number) => {
  let w = AppStorage.get<number>('screenWidth') ?? 375
  let dw = AppStorage.get<number>('designWidth') ?? 375
  return w * len / dw
}

使用

然后就找一个想用上的组件。

js
Column() {

}
.xv(100)