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