# 一、Platform.OS
为了提高代码的兼容性,我们有时需要判断当前系统的平台,然后做一些适配。比如,我们在使用
StatusBar
做导航栏的时候,在iOS
平台下根视图的位置默认情况下是占据状态栏的位置的,我们通常希望状态栏下面能显示一个导航栏,所以我们需要为StatusBar
的外部容器设置一个高度
<View style={{height: Platform.OS === 'ios' ? 20:0}}>
<StatusBar {...this.props.statusBar} />
</View>;
# 二、留意api doc的android或ios标识
并不是所有
React Native
的一些api
或组件的一些属性和方法都兼容Android
和iOS
,在React Native
的api doc
中通常会在一些属性或方法的前面加上android
或ios
的字样来标识该属性或方法所支持的平台,如
android renderToHardwareTextureAndroid bool
ios shouldRasterizeIOS bool
在上述代码中,
renderToHardwareTextureAndroid bool
只支持Android
平台,ios shouldRasterizeIOS bool
只支持iOS
平台,所有我们在使用这些带有标记的属性或方法的时候就需要考虑对于它们不兼容的平台我们是否需要做相应的适配了
# 三、组件选择
比如,我们要开发一款应用需要用到导航组件,
在React Native
组件中有NavigatorIOS
与Navigator
两个导航组件来供我们选择,从api doc
中我们可以看出NavigatorIOS
只支持iOS
平台,Navigator
则两个平台都支持。 所以如果我们要开发的应用需要适配Android
和iOS
,那么Navigator
才是最佳的选择。
为了提高代码的复用性与兼容性建议大家在选择React Native
组件的时候要多留意该组件是不是兼容Android
和iOS
,尽量选择Android
和iOS
平台都兼容的组件。
# 四、图片适配
开发一款应用少不了的需要用到图标。无论是
Android
还是iOS
,现在不同分辨率的设备越来越多,我们希望这些图标能够适配不同分辨率的设备。为此我们需要为每个图标提供1x
、2x
、3x
三种大小的尺寸,React Native
会根据屏幕的分辨率来动态的选择显示不同尺寸的图片。比如:在img
目录下有如下三种尺寸的check.png
└── img
├── check.png
├── check@2x.png
└── check@3x.png
那么我们就可以通过下面的方式来使用check.png
<Image source={require('./img/check.png')} />
提示:我们在使用具有不同分辨率的图标时,一定要引用标准分辨率的图片如
require('./img/check.png')
,如果我们这样写require('./img/check@2x.png')
,那么应用在不同分辨率的设备上都只会显示check@2x.png
图片,也就无法达到图片自适配的效果。
# 五、字体/宽高适配
// utils/FontSize.js
import { PixelRatio, Dimensions } from 'react-native';
let { width, height } = Dimensions.get('window');
export let FontSize = (size) => {
if (PixelRatio === 2) {
// iphone 5s and older Androids
if (width < 360) {
return size * 0.95;
}
// iphone 5
if (height < 667) {
return size;
// iphone 6-6s
} else if (height >= 667 && height <= 735) {
return size * 1.15;
}
// older phablets
return size * 1.25;
}
if (PixelRatio === 3) {
// catch Android font scaling on small machines
// where pixel ratio / font scale ratio => 3:3
if (width <= 360) {
return size;
}
// Catch other weird android width sizings
if (height < 667) {
return size * 1.15;
// catch in-between size Androids and scale font up
// a tad but not too much
}
if (height >= 667 && height <= 735) {
return size * 1.2;
}
// catch larger devices
// ie iphone 6s plus / 7 plus / mi note 等等
return size * 1.27;
}
if (PixelRatio === 3.5) {
// catch Android font scaling on small machines
// where pixel ratio / font scale ratio => 3:3
if (width <= 360) {
return size;
// Catch other smaller android height sizings
}
if (height < 667) {
return size * 1.2;
// catch in-between size Androids and scale font up
// a tad but not too much
}
if (height >= 667 && height <= 735) {
return size * 1.25;
}
// catch larger phablet devices
return size * 1.4;
}
// if older device ie pixelRatio !== 2 || 3 || 3.5
return size;
};
// 统一常用工具入口 utils/tool.js
import { Dimensions, Platform, PixelRatio } from 'react-native';
import {FontSize} from './FontSize';
let { width, height } = Dimensions.get('window');
let pixelRatio = PixelRatio.get();
let screenPxW = PixelRatio.getPixelSizeForLayoutSize(width);
let basePx = Platform.OS === 'ios' ? 750 : 720;
// 像素转dp
let Px2Dp = function px2dp(px) {
var scaleWidth = px * screenPxW*2 / basePx;
size = Math.round((scaleWidth/pixelRatio + 0.5));
return size;
};
export default {
SCREEN_WIDTH: width,
SCREEN_HEIGHT: height,
iOS: Platform.OS === 'ios',
Android: Platform.OS === 'android',
Px2Dp,
FontSize
};
// 使用方式
import Tool from '../../utils/tool'
const styles = StyleSheet.create({
header_info: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
height: Tool.Px2Dp(50),
paddingTop: Tool.Px2Dp(25),
paddingBottom: Tool.Px2Dp(10)
},
text: {
fontSize: Tool.FontSize(14),
color: '#fff',
paddingLeft: 5
},
})