React Native 版本 0.55.4
在使用React native 開發過程中,遇到了很多布局問題。
一、適配各種尺寸的屏幕
React native 要使用一套UI去適配各種屏幕,尤其是安卓擁有著各種尺寸的屏幕。一般設計UI時會參照375*667或者其他一個固定尺寸來進行設計。所以我們應該對設計的內容進行整體的縮放。
通過屏幕寬和設計圖的寬的比例,計算出一個縮放值,然后整個頁面中的所有高度大小相關的style(fontSize,lineHeight,margin,pading,width,height....)都乘以這個縮放值。但是這樣在屏幕寬高比與設計圖寬高比相差比較大的設備上時,可能會出現內容無法放下的情況,比如用375*667的設計圖去按寬縮放時放在4s設備上運行。此時有兩種解決方式,第一種,同時計算縱向的縮放值,與橫向的縮放值做比較,取更小比例的值。
class Constant {
//static 關鍵字用來定義一個類的一個靜態方法。調用靜態方法不需要實例化該類,但不能通過一個類實例調用靜態方法。靜態方法通常用于為一個應用程序創建工具函數。
/* widthStandard : 設計圖寬度 默認375
* heightStandard : 設計圖高度 默認667
*/
static getPortraitScale = (widthStandard=375, heightStandard = 667) => {
//取短的為寬
let w = Dimensions.get("window").width;
let h = Dimensions.get("window").height;
let screenW = w > h ? h : w;
let screenH = w > h ? w : h;
//使用strand縮放后內容的高度
let height = screenW / widthStandard * heightStandard;
if (height < screenH) {
return screenW / widthStandard;
}
return screenH / heightStandard;
};
//橫屏獲取縮放比
static getLandscapeScale = (widthStandard=667, heightStandard = 375) => {
//取長的為寬
let w = Dimensions.get("window").width;
let h = Dimensions.get("window").height;
let screenW = w < h ? h : w;
let screenH = w > h ? h : w;
//使用strand縮放后內容的高度
let height = screenW / widthStandard * heightStandard;
if (height < screenH) {
return screenW / widthStandard;
}
return screenH / heightStandard;
};
}
二、橫豎屏切換的問題
1.調整設備設置中的字體大小時,出現字體布局混亂的情況
安卓和iOS系統的設置中都有一個可以選擇字體大小的選項。如果把字體放大后,App可能會出現文字布局混亂的情況。尤其在使用了lineHeight
style后,文字可能會發生截斷的情況。
解決方案:在<Text/>
中使用allowFontScaling={false}
這個allowFontScaling可以用來解決字體同時放大的問題,但是這個參數有一些版本限制,在react-native 0.3X之前,這個參數只適用于iOS設備(網上查的資料,未證實)。
在0.51版本之前這個參數即使使用了,會有一個非常奇怪的bug,文字確實不會放大縮小,但是lineHeight
還是會放大縮小。所以仍然有截斷現象。而在目前最新的0.55.4的版本中bug被修復。顯示正常。
2.Navgation Bar高度不一致問題
使用自定義的Bar時。安卓和iOS高度不一致。Android計算Nav高度是從手機頂部開始計算。而iOS默認會向下偏移狀態欄的高度。要做到效果統一。需要將安卓的Bar的paddingTop
屬性設為狀態欄高度
import {StatusBar, Platform} from "react-native";
navigationOptions = {
...
headerStyle: {
...
paddingTop: Platform.OS === "ios" ? 0 : StatusBar.currentHeight,
},
}
另外橫屏后,iOS的橫屏時navigation bar的高度只有32px 而安卓的不會改變
或者
使用React-Navigation 中的SafeArea ,將 <SafeArea/>
包裹在根視圖的最外層。此時視圖是從狀態欄下方開始布局的。