React Native 屏幕適配

開發APP(包括H5)都面臨一個問題,怎麼適配各種尺寸的屏幕?

H5方案:等比例縮放

在移動端的web頁面適配上,我們採用的是手機淘寶出的 lib-flexible 方案,大部分情況下,rem 一把梭,基本上解決了屏幕適配問題。

React Native的頁面布局裡,也很自然想到使用類似的方案,根據當前屏幕寬度,計算出應該顯示的尺寸,梭哈即可。然鵝,在和UE同學確認時,才知道移動端H5的方案,他們並不太滿意,換句話,UE在很多情況下,並不希望界面按照屏幕尺寸來等比縮放。

RN 里怎麼適配

和APP同學溝通之後,了解到了APP端之前的一些做法,再參考了一些業界方案,大體情況下,適配可以分成以下幾種情況:

  • 固定尺寸(按鈕、文字大小、間距)
  • 保持寬高比(比如banner圖片)
  • 間距固定,內容自適應(比如產品卡片寬度)
  • 按屏幕等比縮放

再拿到UI設計稿後,對布局、尺寸自適應不夠清楚的,直接和UE同學確認具體的適配方式,一般都對應到上述情況之一。

針對以前Android和iOS同學,使用的2套設計稿的情況(Android用1080,iOS用750),統一使用 750px的iPhone設計稿 ,設計同學只出一套設計稿,圖片仍然給 @2x @3x 兩套。

針對上述4種情況,統一提供幾個工具函數,方便開發同學使用。開發同學拿到750的設計稿,量出某個尺寸,直接使用下面幾個工具函數之一,來處理各種情況:

  • px2dp: 不做 等比例縮放,返回 @1x 的大小
  • scalePx2dp: 根據當前 屏幕寬度 和750的比例,等比的計算當前屏幕下對應的大小

最後,針對上述幾種適配情況,基本上這樣來處理:

  • 固定尺寸: 使用 px2dp 得到固定大小 (大多數尺寸都用固定尺寸)
  • 保持寬高比:建議使用 aspectRatio
  • 間距固定,內容自適應:使用 flex 布局
  • 按屏幕等比縮放:使用 scalePx2dp

在實際布局中,大的塊級布局,塊級組件,寬度 應該盡量使用 flex 布局,避免 寬度 也使用 固定尺寸 來實現。

aspectRatio 用法

在保持寬高比的情況下,我們應該儘可能使用 aspectRatio 來實現,比如,有個圖片,在 750設計稿 里量來是 126*134 ,寬度占父級的 50%,我們可以這樣來實現:

const style = {
width: 50%,
// **注意**,下面這個 height: undefined 樣式,在載入 **本地圖片** 時,是必須的!
height: undefined,
aspectRatio: 126 / 134,
};
//later in render
<Image style={style}></Image>

兩側間距固定,中間自適應

比如,有個 View 組件,需要保持屏幕兩側間距為 20dp,內容自適應,我們可以這樣實現:

const style = {
marginHorizontal: 20,
alignSelf: stretch,
};
//render
<View style={style}></View>

StyleSheet.create VS global JSON VS inline JSON

在寫 style 的時候,根據 RN官方文檔,應該使用 StyleSheet.create 來生成樣式,這樣寫能 提升性能。然鵝,根據源碼和issue的情況來看,目前來說,[email protected]版本,StyleSheet.create內部並沒有任何提升性能的操作,只是單純的返回了傳入的 JSON,當然,在 DEV模式下,會校驗下style的屬性。可以參考 這個commit 和 這個issue 。

雖然 StyleSheet.createglobal JSON style 樣式相比,沒有什麼性能提升;但是和 inline JSON 的樣式相比,還是有一些優勢的。inline JSON style 如果數據比較多,會讓代碼可讀性降低,並且每次 render 都會構造新的對象,這也是一種損耗。

不過,儘管目前 StyleSheet.create 沒神馬X用,我們還是統一調用 StyleSheet.create 來生成樣式吧,萬一在將來哪個版本,傳說中的性能提升又悄悄加上了呢……

相關資料

  • react-native-size-matters
  • REACT NATIVE SUPPORT MULTIPLE SCREEN SIZES
  • github.com/nirsky/react
  • 手機淘寶iphone適配協作模式

推薦閱讀:

相关文章