weex代码中的高度和宽度的单位均为px,然而,在手机屏幕上显示的高宽却不必定与代码指定的相同。缘由是weex框架在底层作了针对不一样屏幕的适配工做,具体计算公式为 实际高宽 = 代码高宽 * (屏幕宽度 / 750)。css
举个例子,假设代码中是这么写的:weex
<style> .button { height: 100; width: 200; } </style>
那么,在一款屏幕分辨率为1920*1280的Android手机上,此时的计算过程为:
height: 100 * (1080 / 750) = 144;
width: 200 * (1080 / 750) = 288。框架
若是咱们开发的weex页面是全屏幕的,那么这个高宽的转换过程对咱们而言是透明的,无需作额外的工做。然而一旦有一个业务场景,weex容器并不是是全屏幕的,而是须要从外部传入weex容器的高度,那么,就不得不考虑这个转换的过程。ui
举一个我在开发weex弹窗时的例子。该weex弹窗的样式以下:this
能够看到,若是不考虑多屏幕适配,顶栏和底栏都是一个固定值,那么只须要用总容器高度 - 两个定高组件就能够了。那么须要解决的第一个问题,就是如何获取外部容器的高度。因为weex能够经过$getConfig().env.deviceHeight
和$getConfig().env.deviceWidth
的形式来获取手机屏幕的高度,于是,很天然地就想到,是否能在安卓中以屏幕的3/5的比例,约定容器高度,而后在weex代码中,一样经过3/5来计算容器高度。这样就避免了去写 Native Module 和 Method。spa
然而,这样的思路是不可行的。由于Android Native的总高度,事实上是可供显示的全屏高度,而不必定是物理屏幕的高度,由于有状态栏,虚拟按键栏,Smartbar等等安卓碎片化引入的额外显示元素,实际全屏高度颇有可能小于物理屏幕高度。因此,仍然须要开发和注册Native Module,以获取外部容器高度。code
再来看上文的计算公式:总容器高度 - 两个定高 = scroller高度。由于多屏幕适配的缘由,上面的公式是不可行的,须要改成:orm
外部传入的总容器高度 - 两个定高组件的高度字面量 * 转换比例 = scroller实际高度blog
也就是说:外部传入的总容器高度 / 转换比例 - 两个定高组件的高度字面量 = scroller实际高度 / 转换比例 = scroller的字面量高度。开发
因此,最终的业务代码以下所示:
ready:function() { ... // 引入外部注册的 Native Module;Android 和 iOS 各有其实现 var AppInfo = require('@weex-module/MSOAFoundation'); if (this.$getConfig().env.platform != "iOS") { // 适配 Android this.mainExtra = "mainExtraAndroid"; AppInfo.getContainerHeight(function(params) { ratio = this.$getConfig().env.deviceWidth / 750; this.scrollerHeight = params.height / ratio - 200; }.bind(this)); } else { // 适配 iPhone 4S if (this.$getConfig().env.deviceHeight < 1000) { this.scrollerHeight = 700; } } ... }
这个坑很是的隐蔽,本质是由于:weex 默默作了A参考系转换到B参考系的过程,然而一旦咱们自力更生,试图从B参考系得到一个测量获得的高度,用在A参考系,而没意识到这个隐蔽的转换过程的时候,就会陷入到一台机子上调好了,另外一台又跪了的尴尬局面。并且,这种状况在Android上远较iOS要来的严重。由于iOS上,除了4S之外,5,5s,6,6p,6s,6sp,屏幕尺寸均为同一长宽比。所以,在一台上调整好后,可无缝等比例放大到其余机型上。然而在Android上,毋论碎片化的屏幕尺寸,光status bar,navigation bar,smartbar等等虚拟的占用实际显示区域的各种bar,就足够让weex的默认适配喝一壶的。所以,weex这种隐蔽适配的处理方式,在Android生态上是否真的合理方便,尚待商榷。
====================================
若是您以为个人文章对您有所启迪,请点击文末的推荐按钮,您的鼓励将会成为我坚持写做的莫大激励。 by DesGemini