一个应用如何适配手机、平板和折叠屏等?(一开多发,全局断点)

155 阅读2分钟

一个应用如何适配手机、平板和折叠屏等?(一开多发,全局断点)

随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用、互助共享,让用户享受无缝的全场景体验,即一套代码工程,一次开发上架,多端按需部署。

我们可以根据当前设备屏幕的尺寸,来渲染出不同的界面效果

那么如何获取到当前屏幕的尺寸呢?

思考表情包熊猫头 的图像结果

我们发现在生命周期EntryAbility中,我们可以在onWindowStageCreate也就是窗口创建阶段,通过windowStage.getMainWindow() 获取主窗口对象,监听窗口大小变化。

  • 当窗口大小发生变化时,计算窗口宽度从像素(px)转换为虚拟像素(vp)。
  • 根据窗口宽度的vp值,判断当前设备属于哪个断点范围(xs, sm, md, lg)。
  • 如果新的断点值与当前记录的断点值不同,则更新断点值并存储到 AppStorage 中。
onWindowStageCreate(windowStage: window.WindowStage): void {
​
    ......
    
    windowStage.getMainWindow()
      .then((windowObj) => {
        windowObj.on('windowSizeChange', (windowSize) => {
          try {
            // 1. 将长度的单位由px换算为vp,(px除以像素密度得到vp)
            let windowWidthVp = windowSize.width / display.getDefaultDisplaySync().densityPixels
            let newWindow: string = ''
            let oldWindow: string = ''
            // 2. 基于窗口宽度vp值,判断当前设备属于哪个断点范围
            if (windowWidthVp < 320) {
              newWindow = 'xs'
            } else if (windowWidthVp < 600) {
              newWindow = 'sm'
            } else if (windowWidthVp < 840) {
              newWindow = 'md'
            } else {
              newWindow = 'lg'
            }
            if (oldWindow !== newWindow) {
              oldWindow = newWindow
              // 3. 使用状态变量记录当前断点值
              AppStorage.setOrCreate('currentBreakpoint', oldWindow)
            }
          } catch (err) {
            console.log(err.code)
          }
        })
      })
}

在目标页面通过下面代码就可以获取

// 获取 AppStorage 保存的全局断点(EntryAbility.ets)
@StorageProp('currentBreakpoint') currentBreakpoint: string = ''

就可以达到以下效果(以下分别为 手机、折叠屏和平板)

image.png

image.png

image.png

细心地小伙伴应该发现了,在冷启动时并不会触底这个效果,所以我们要获取应用启动时的窗口尺寸,不妨让我们把这个方法封装起来。

private updateWindowWidth(windowWidth: number): void {
  try {
    // 1. 将长度的单位由px换算为vp,(px除以像素密度得到vp)
    let windowWidthVp = windowWidth / display.getDefaultDisplaySync().densityPixels
    let newWindowWith: string = ''
    let oldWindowWith: string = ''
    // 2. 基于窗口宽度vp值,判断当前设备属于哪个断点范围
    if (windowWidthVp < 320) {
      newWindowWith = 'xs'
    } else if (windowWidthVp < 600) {
      newWindowWith = 'sm'
    } else if (windowWidthVp < 840) {
      newWindowWith = 'md'
    } else {
      newWindowWith = 'lg'
    }
    if (oldWindowWith !== newWindowWith) {
      oldWindowWith = newWindowWith
      // 3. 使用状态变量记录当前断点值
      AppStorage.setOrCreate('currentBreakpoint', oldWindowWith)
    }
  } catch (err) {
    console.log(err.code)
  }
}
​
onWindowStageCreate(windowStage: window.WindowStage): void {
​
  ...
​
  windowStage.getMainWindow()
    .then((windowObj) => {
      // 获取应用启动时的窗口尺寸
      this.updateWindowWidth(windowObj.getWindowProperties().windowRect.width)
      // 监听窗口尺寸变化
      windowObj.on('windowSizeChange', (windowSize) => {
        this.updateWindowWidth(windowSize.width)
      })
    })
    
}

这样就大功告成了~!!!🎉🎉🎉