Author:Mr.柳上原
- 付出不亞于任何的努力
- 愿我們所有的努力,都不會被生活辜負
- 不忘初心,方得始終
既然已經入了react坑
那自然不會少了移動端app開發神器RN
初衷依然是把自己在公司實際開發中遇到的踩坑填坑過程記錄下來
給自己
也分享給同樣從事這行的各位新入行朋友做個爬坑指南
首先
reactNative我在這里簡稱RN
RN是可以做跨平臺開發的
這就導致了一個問題
RN的組件,在Android和ios上有些會有所不同
RN的樣式編輯,在Android和ios上有些也會有所不同
這就涉及到了平臺兼容
比較常見的兼容問題有:
大小,寬高,字體,不同手機系統的獨占組件等等
如何解決這些問題
我是這樣做的:
// 關于寬高大小
// 解決思路為,封裝一個獨立的工具函數,來處理手機不同大小尺寸的兼容
/**
* Created by zhuoy on 2017/6/27.
* 屏幕工具類
* ui設計基準,iphone 6
* width:750
* height:1334
*/
/*
設備的像素密度,例如:
PixelRatio.get() === 1 mdpi Android 設備 (160 dpi)
PixelRatio.get() === 1.5 hdpi Android 設備 (240 dpi)
PixelRatio.get() === 2 iPhone 4, 4S,iPhone 5, 5c, 5s,iPhone 6,xhdpi Android 設備 (320 dpi)
PixelRatio.get() === 3 iPhone 6 plus , xxhdpi Android 設備 (480 dpi)
PixelRatio.get() === 3.5 Nexus 6 */
import { Dimensions, PixelRatio } from 'react-native';
export const deviceWidth = Dimensions.get('window').width; //設備的寬度
export const deviceHeight = Dimensions.get('window').height; //設備的高度
let fontScale = PixelRatio.getFontScale(); //返回字體大小縮放比例
let pixelRatio = PixelRatio.get(); //當前設備的像素密度
const defaultPixel = 2; //iphone6的像素密度
//px轉換成dp
const w2 = 750 / defaultPixel;
const h2 = 1334 / defaultPixel;
const scale = Math.min(deviceHeight / h2, deviceWidth / w2); //獲取縮放比例
const scaleWidth = deviceWidth / w2
/**
* 設置text為sp
* @param size sp
* return number dp
*/
export function setSpText(size) {
size = Math.round((size * scale + 0.5) * pixelRatio / fontScale);
return size / defaultPixel;
}
export function scaleSize(size) { // 不適用小比例縮放
size = Math.round(size * scaleWidth);
return size / defaultPixel;
}
export function scaleWidthSize(size) {
size = Math.round(size * scaleWidth);
return size / defaultPixel;
}
// 一般我們會使用scaleSize這個函數,其他特殊地方使用另外兩個函數處理
//使用方法
// 在頁面引入該工具函數
import { scaleSize } from "../utils/screenUtil";
// 在標簽內部寫入行間樣式
<View style={{marginRight: scaleSize(40)}}>
</View>
// 在css里寫入外部樣式
// 外部樣式引用工具函數的方法:把外部樣式用js寫法表示
import { scaleSize } from "../utils/screenUtil";
const styles = StyleSheet.create({
ListItem: {
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 15,
paddingRight: 15,
height: scaleSize(100),
justifyContent: 'space-between',
},
status: {
position: 'absolute',
right: scaleSize(15),
top: scaleSize(15),
},
numberInput: {
paddingRight: scaleSize(20),
},
})
// 然后把該外部樣式引入需要的頁面
import { styles } from "../css/styles ";
// 調用該樣式
<View style={styles.ListItem, styles.status, styles.numberInput}>
</View>
// 復合寫法
// 同時使用外部樣式和行內樣式
<View style={[styles.ListItem, styles.status, styles.numberInput, {marginRight: scaleSize(40)}]}>
</View>
// 關于字體
// 需要注意一點
// ios改變字體需要在node_modules里引入字體庫并進行關聯設置,不然開發ios app的時候使用自定義字體時會報錯,具體設置百度上都有
// 簡單的方法是:如果Android實在需要自定義字體,可以使用系統監控,做ios的兼容判斷,去除ios自定義字體
import { Platform } from 'react-native';
const ios = Platform.OS === 'ios';
<View style={{
display: 'flex', flexDirection: 'column',
fontFamily: ios ? null : "PingFangSC-Regular",
}}>
</View>
// 關于兼容
// 跨平臺兼容的思想就是系統監控,不同的系統做兼容判斷
import { Platform } from 'react-native';
const ios = Platform.OS === 'ios';
// 比如
<View style={{
display: 'flex', flexDirection: 'column',
fontFamily: ios ? null : "PingFangSC-Regular",
}}>
</View>
// 比如
<TabBar.Item title='首頁'
icon={ ios ? require('./images/sy_ios_select.png') : require('./images/sy.png')}
selectedIcon={ ios ? require('./images/sy_ios_select.png') : require('./images/sy_select.png')}
selected={this.state.selectedTab === 'index'} onPress={() => {Toast.hide(); this.changeTab('index');}}>
{
this.state.selectedTab === 'index'
? <View style={[LayerStyles.xyhLayer, {bottom: tabBottom}]}>
{Platform.OS === 'android' ? null : <StatusBar translucent={true} backgroundColor="rgba(0, 0, 0, 0.2)" />}
{
<View style={[LayerStyles.scrollPanel, { backgroundColor: 'transparent', zIndex: 1 }]}>
{this.props.topbar}
{children}
</View>
}
{
this.props.pageBackground
? this.props.pageBackground
: null
}
{
this.props.showLoading
? (<Spinner />)
: null
}
</View>
: null
}
</TabBar.Item>