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

  gUpdateScale(scale: number) => {
    AppStorage.setOrCreate(uiAppStorageScale, scale)
  }

  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)

        let dis = display.getDefaultDisplaySync()
        if (dis.orientation == display.Orientation.PORTRAIT) {
          if (wvp < 520) {
            AppStorage.setOrCreate(uiAppStorageIsWidthScreen, false)
            gUpdateScale(wvp / gDesignWidth)
          } else {
            AppStorage.setOrCreate(uiAppStorageIsWidthScreen, true)
            gUpdateScale(wvp / 2 / gDesignWidth)
          }
        } else {
          if (hvp < 520) {
            AppStorage.setOrCreate(uiAppStorageIsWidthScreen, false)
            gUpdateScale(wvp / gDesignWidth)
          } else {
            AppStorage.setOrCreate(uiAppStorageIsWidthScreen, true)
            gUpdateScale(wvp / 2 / gDesignWidth)
          }
        }
      }
    }
  }

  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
@StorageProp(uiAppStorageScale) designScale: number = 1
Column() {

}
.width(100 * this.designScale)

这样就能在折叠屏打开操作之类的操作上,屏幕宽度会自动适配。