不同像素密度,不同尺寸设备如何适配?
问题描述
设计稿是以360vp * 800vp的手机作为标准来设计的,比如图片的尺寸标注为了:10vp * 10vp,那代码中如何指定width/height呢?
错误写法: 10px / 10vp / 10
原因分析:
以下分析鸿蒙中适配问题
HarmonyOS中提供的长度像素单位为:px 与 vp
px: Pixel,屏幕物理像素单位。
问题:相同px值在不同像素密度的手机上显示的尺寸是不同的
注意:不同于CSS中的px,CSS中的px类似于下面的vp
vp: Virtual Pixel,虚拟像素
它是屏幕像素密度相关像素,应用运行时,会根据屏幕像素密度转换为屏幕物理像素进行显示,在不同像素密度的手机上,1vp对应的像素数是不同的,像素密度越高,1vp对应的像素数就越多。从而达到:用vp作为长度单位,在尺寸相同但像素密度不同的手机上,显示大小相同。
当数值不带单位时,默认单位为vp。
HarmonyOS提供了针对运行设备的vp与px转换的全局计算函数
px2vp(val): 得到指定px值对应的vp值
vp2px(val): 得到指定vp值对应的px值
解决方案:
○ 1. 得到屏幕宽度的像素数 width
○ 2. 计算出屏幕宽度的vp值:vp = px2vp(width)
○ 3. 计算出适配时需要缩放的比例值:vpScale = vp/360
○ 4. 计算出图片要指定的width和height值:10 * vpScale
具体转换:
// 获取屏幕宽度,进行缓存
let windowWidth: number;
export function getWindowWidth() {
if (windowWidth) return windowWidth;
// 获取到的屏幕宽度是px单位
const storageWindowWidth = AppStorage.Get<number>('windowWidth');
if (storageWindowWidth) {
// 将屏幕宽度转化为vp单位
windowWidth = px2vp(storageWindowWidth)
} else {
// 预览器没法获取屏幕宽度,所以读取的到值为0,会进入这里,我们给默认值360
windowWidth = 360
}
return windowWidth
}
// 将元素按照原来比例进行转化
export default function responsiveVP(val: number) {
/*
* 设计稿总宽度:360 (固定值)
* 设计稿某个元素大小:120 -> val
* 实际设备屏幕宽度:400 -> 通过 window.getWindowProperties().windowRect.width 方式获取, 得到单位是 px,需要转 vp 计算
* 元素实际大小:x
* x / 400 = val / 360
*
* 解方程式得出: x = val / 360 * 实际设备屏幕宽度
*/
return val / 360 * getWindowWidth()
}
在代码中调用这个函数responsiveVP使用,如:responsiveVP(10)