一个应用如何适配手机、平板和折叠屏等?(一开多发,全局断点)
随着终端设备形态日益多样化,分布式技术逐渐打破单一硬件边界,一个应用或服务,可以在不同的硬件设备之间随意调用、互助共享,让用户享受无缝的全场景体验,即一套代码工程,一次开发上架,多端按需部署。
我们可以根据当前设备屏幕的尺寸,来渲染出不同的界面效果
那么如何获取到当前屏幕的尺寸呢?
我们发现在生命周期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 = ''
就可以达到以下效果(以下分别为 手机、折叠屏和平板)
细心地小伙伴应该发现了,在冷启动时并不会触底这个效果,所以我们要获取应用启动时的窗口尺寸,不妨让我们把这个方法封装起来。
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)
})
})
}
这样就大功告成了~!!!🎉🎉🎉