在正文开始之前 首先得了解一下我们设计稿的1px在手机中是怎样显示出来的,首先看下图
从上图得知了各个安卓和IOS常规屏幕的宽高以及像素比,在日常设计稿常以iPhone6 750px(375 * 2 = 750) 为标准设计,从以上信息得知我们设计稿中的1px 在iPhone6中是占据了2px
下面将以10px为单位在每一个型号进行单位换算
型号 | 宽度 | 高度 | 设计稿单位(宽度) | 像素比 | 转换单位(10px) |
---|---|---|---|---|---|
iPhone5 | 320 | 568 | 640 | 2 | 20 |
iPhone6 | 375 | 667 | 750 | 2 | 20 |
iPhone6 Plus | 414 | 736 | 1242 | 3 | 30 |
iPhone7 | 375 | 667 | 750 | 2 | 20 |
iPhone7 Plus | 414 | 736 | 1242 | 3 | 30 |
iPhone X | 375 | 812 | 1125 | 3 | 30 |
Nexus 5 | 360 | 640 | 1080 | 3 | 30 |
Nexus 5x | 411 | 731 | 1078.875 | 2.625 | 26.25 |
Nexus 6 | 412 | 732 | 1536 | 3.5 | 35 |
从上表发现了一个规律 以iPhone6与iPhone6 Plus 为例 转换单位是由 像素比 * 转换单位 得出 由此推算得出单位转换公式
(像素比 * 转换单位)/ 像素比
例子:
(2 * 10)/ 2 = 10//iPhone6
(3 * 10)/ 3 = 10//iPhone6 Plus
那么得到了需要转换的单位后怎么进行适配呢,首先要得到系统状态栏高度,利用小程序API wx.getSystemInfo(Object object)(官方文档传送门)中的statusBarHeight得到了系统状态栏高度(解决万恶的刘海屏,水滴屏问题),现在问题最大的系统状态栏高度已经获取到之后就可以开始写了
mpvue代码:
App.vue
<script>
export default {
getSysInfo() {
const res = wx.getSystemInfoSync()
return res
}
};
</script>
<style>
.container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 0;
box-sizing: border-box;
background-color: #ccc;
}
page {
width: 100%;
height: 100%;
background-color: red;
}
</style>
组件文件: frames.vue
<template>
<div class="frameContainers">
<header
class="headNav"
:style="{ paddingTop: statusBarHeight + 'px', height: navHeight + 'px' }"
>
<section class="headArea" :style="{ height: headAreaHeight + 'px', marginTop: headAreaMarTop + 'px' }">
<div class='leftBox'></div>
<div class='rightBox' :style="{ width: headRightBoxW + 'px' }"></div>
</section>
</header>
<scroll-view scroll-y scroll-with-animation class="contentArea" :style="{ height: containersHeight + 'px' }">
<div v-for="item in 50" :key='item'>
{{ item }}
</div>
</scroll-view>
</div>
</template>
<script>
import app from "../App";
export default {
props: ["text"],
data() {
return {
pixelRatio: app.getSysInfo().pixelRatio, //系统像素比
statusBarHeight: app.getSysInfo().statusBarHeight, //系统状态栏高度
navHeight: "", //顶部导航栏高度
headAreaHeight:app.getSysInfo().pixelRatio * 35 / app.getSysInfo().pixelRatio, //顶部内容区域高度
headAreaMarTop: "", //顶部内容区域外边距
headleftBoxW: "", //顶部内容左侧区域外边距
headRightBoxW: "", //顶部内容右侧区域外边距
containersHeight: "", //页面内容区域高度
};
},
mounted () {
//IOS 与 安卓进行差异化处理
if (app.getSysInfo().system.substring(0, 3) == "iOS") {
this.navHeight = this.pixelRatio * 40 / this.pixelRatio;
this.headAreaMarTop = this.pixelRatio * 0.5 / this.pixelRatio;
this.headleftBoxW = app.getSysInfo().windowWidth - this.pixelRatio * 100 / this.pixelRatio;
this.headRightBoxW = this.pixelRatio * 100 / this.pixelRatio;
this.containersHeight = app.getSysInfo().windowHeight - (this.statusBarHeight + this.pixelRatio * 40 / this.pixelRatio);
} else {
this.navHeight = this.pixelRatio * 45 / this.pixelRatio;
this.headAreaMarTop = this.pixelRatio * 2.5 / this.pixelRatio;
this.headleftBoxW = app.getSysInfo().windowWidth - this.pixelRatio * 110 / this.pixelRatio;
this.headRightBoxW = this.pixelRatio * 110 / this.pixelRatio;
this.containersHeight = app.getSysInfo().windowHeight - (this.statusBarHeight + this.pixelRatio * 45 / this.pixelRatio);
}
}
};
</script>
<style scope>
.frameContainers {
width: 100%;
height: 100%;
}
.headNav {
background-color: red;
display: flex;
align-items: center;
}
.headArea {
width: 100%;
background-color: aqua;
}
.contentArea {
background-color: yellow;
}
.rightBox {
width: 18vh;
height: 100%;
background-color: cadetblue;
float: right;
}
</style>
调用组件页面index.vue
<template>
<div class="container">
<frames></frames>
</div>
</template>
<script>
import frames from "@/components/frame";
export default {
components: {
frames
},
};
</script>
<style scoped>
</style>
效果图:
安卓水滴屏 OPPP R17
IOS刘海屏 苹果X
安卓常规屏 OPPO R11S
IOS常规屏 苹果8