1. 前言
在使用
react-native
進行開發的時候我們參見官方文檔知道做螢幕适配是使用
flexBox
來進行布局.
戳我檢視 flexBox 布局
有關
flexBox
的屬性這裡不做太多介紹,不會的請參考官方文檔.這裡隻是說一下在做螢幕适配的時候發現僅僅使用
flexBox
還有點不太夠用~
在
react-native
中我們使用
StyleSheet
這個對象來進行樣式的開發.示例代碼如下所示:
import { StyleSheet } from "react-native";
// 聲明了一個style的變量,使用它來給元件添加樣式
let style = StyleSheet.crate({
title: {
fontSize: 14,
color: "#BBB",
},
subTitle: {
marginTop: 10,
marginBottom: 10,
paddingLeft: 10,
paddingRight: 10,
},
});
可以看到在
react-native
中寫樣式和在
web
中寫
css
還是有很大的差別的.哪些好用的
less
,
sass
等基本上不可以用.而且也不可以
用複合樣式
.例如:
web 中寫樣式
/* web */
.title {
padding: 10 20 15 5;
}
react-native 中寫樣式
/* react-native */
title:{
paddingTop:10,
paddingRight:20,
paddingBottom:15,
paddingLeft:5
}
可以看到在
rn
中寫樣式還是有點麻煩~
2. 使用 flexbox
布局
flexbox
flexBox
給我們提供了很友善的布局方法,但是有時候我們還是需要一些正常屬性,例如:
width
,
height
,
paddingTop
,
fontSize
等等...因為在
rn
中樣式是沒有機關的(預設
dp
),那麼這個時候問題就來了,在不同的螢幕上它的
dpi
是不同的,如何做适配呢?
通過檢視官方文檔,找到了解決方法.封裝了一個方法
dp2px
,代碼如下所示:
import { Dimensions } from "react-native";
const deviceWidthDp = Dimensions.get("window").width;
// 預設設計稿375
const uiWidthPx = 375;
function dp2px(uiElementPx) {
return (uiElementPx * deviceWidthDp) / uiWidthPx;
}
export default dp2px;
這樣在開發中如果需要使用一些
寬度
,
高度
等屬性的時候直接引用這個方法就可以了.如下所示:
import dp2px from './dp2px';
title:{
paddingTop:dp2px(10),
paddingRight:dp2px(20),
paddingBottom:dp2px(15),
paddingLeft:dp2px(5)
}
這樣就完成了适配的工作.但是這個就是最優解了麼,顯然不是.每次寫樣式的都需要把這個函數引用進來,而且每次都要寫大量的
dp2xp
,實在是非常的麻煩.那麼問題來了,我們如何優化?
3. 封裝 CustomStyleSheet 代替原生 StyleSheet
通過翻看源碼,發現
StyleSheet
不是一個類,我們不需要繼承它,重寫它的這個方法,隻需要自己封裝一個類似
StyleSheet
這樣的一個函數在它的内部進行一些計算,然後在需要寫樣式的地方,統一使用我們的
CustomStyleSheet
代替原生的
StyleSheet
即可.代碼如下所示:
import { StyleSheet } from "react-native";
import dp2px from "./dp2px";
let MyStyleSheet = {
create(style) {
let s = { ...style };
// 目前僅對以下的屬性進行處理
let list = [
"width",
"height",
"marginTop",
"marginBottom",
"marginLeft",
"marginRight",
"paddingTop",
"paddingRight",
"paddingBottom",
"paddingLeft",
"top",
"right",
"bottom",
"left",
"fontSize",
"lineHeight",
];
for (outKey in s) {
for (innerKey in s[outKey]) {
if (
list.includes(innerKey) &&
typeof s[outKey][innerKey] == "number"
) {
s[outKey][innerKey] = px2dp(s[outKey][innerKey]);
}
}
}
return StyleSheet.create(s);
},
};
export default MyStyleSheet;
通過上述封裝後使用起來就很友善了.在
react-native
元件中直接使用它來代替原生的
StyleSheet
即可.例如:
import MyStyleSheet from "./myStyleSheet";
// 使用封裝好的MyStyleSheet來代替原生StyleSheet,直接寫數字即可自動轉換為不同螢幕适配的dp
let style = MyStyleSheet.create({
title: {
fontSize: 14,
width: 100,
},
subTitle: {
paddingTop: 10,
paddingBottom: 10,
marginTop: 10,
marginBottom: 10,
},
});
至此,結束.附上相關資料,供學習