reactNative跨平臺app開發經驗分享-跨平臺開發兼容

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>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。