起點RN Demo安卓遷移問題匯總

1. 三方庫(調(diào)用原生)的使用

這里的三方庫特指需要調(diào)用原生的庫,目前項目里用到了react-native-share(分享)、react-native-linear-gradient(漸變)、react-native-splash-screen(閃屏)、react-native-svg(svg)。
正常我們使用react-native link命令,原生依賴就成功地鏈接到你的iOS/Android項目了,但出于原生代碼可能被改寫的情況,需要在原生代碼中確認一下引入情況:

2. lineHeight

在遷移過程發(fā)現(xiàn)幾個頁面都出現(xiàn)一下錯誤提示:

Error while updating property 'lineHeight' in shadow node of type:RCTText

查文檔給出的解釋:

lineHeight must be an integer, numbers with decimals are not considered as valid values.

原來安卓上lineHeight必須是整數(shù),由于我們的項目中用了p2dp進行適配,會有把整數(shù)轉(zhuǎn)成了小數(shù)的情況,解決方法就是p2dp的結(jié)果進行向上取整。

3. 字體引入

安卓上要使用自定義的字體,必須要把字體文件放在[project root]/android/app/src/main/assets/fonts/目錄下才能生效。

4. StatusBar

StatusBar是一個值得被重視的差異,它會影響到頭部導(dǎo)航的高度樣式問題,甚至是整個頁面的高度問題。

4.1 StatusBar高度

  • 4.1.1 Android 手機狀態(tài)欄
    (1)當狀態(tài)欄呈現(xiàn)在 Andorid 手機屏幕頂部時,它會占用頂部這個空間,我們只能使用剩下的屏幕空間。也就是說如果從第 0 行開始放置組件時,組件會緊貼著狀態(tài)欄的下邊沿顯示;
    (2)要想知道實際可用的屏幕高度,可以通過手機屏幕的高度減去狀態(tài)欄高度得到,安卓狀態(tài)欄的高度可通過StatusBar.currentHeight獲取。
  • 4.1.2 iOS 手機狀態(tài)欄
    (1)在 iOS 平臺上,取得的屏幕高度就是實際可使用的高度;
    (2)如果從第 0 行開始排列組件時,組件會緊貼著手機屏幕的最上沿顯示。如果狀態(tài)欄沒有被隱藏,它將覆蓋在第 0 行組件的上方;
    (3)如果不想設(shè)置狀態(tài)欄隱藏,則應(yīng)當空出狀態(tài)欄的顯示區(qū)域。但可以為這個區(qū)域設(shè)置背景色,以使整個界面風(fēng)格統(tǒng)一。

4.2 StatusBar樣式

Default status bar style (dark for iOS, light for Android)

在Android上默認的樣式是白色,而IOS是黑色,所以當我們在跨平臺設(shè)置StatusBar樣式時,避免使用defult,應(yīng)該直接使用light-content、dark-content

4.3 StatusBar背景色

Android上可通過backgroundColor設(shè)置背景色,而IOS無此屬性,需要通過手動設(shè)置20dp高度的顏色作為背景色。另外項目中有個特殊需求,需要StatusBar的顏色是漸變的,這時安卓上需要讓背景色透明,設(shè)置同等高度的漸變色來替代。

5. 閃屏、廣告頁面

因為閃屏涉及端代碼的編寫,自然需要重新開發(fā)。
廣告頁面則有兩個思路:可以在端開發(fā)、也可以放在RN:

  • 在端的好處在于RN的首頁是"真首頁",在啟動應(yīng)用顯示閃屏的時候,為預(yù)加載首頁提供了時間,讓首頁出現(xiàn)的時間大大提升;缺點就是不夠靈活,如果將廣告圖換一個表現(xiàn)形式,需要重新發(fā)包。
  • 在RN的好處自然就是靈活,可以頻繁的變換廣告形式也無需更新App,另外如果是復(fù)雜的廣告形式,對于前端開發(fā)人員,開發(fā)端代碼的陳本要遠高于開發(fā)RN;缺點就是RN的首頁變成了廣告頁,而不是我們想要的首頁,這樣啟動圖無法爭取到首頁的訪問的時間,在首頁呈現(xiàn)的時間上肯定比上面的方法慢一些。

6. 輪播組件

這個問題涉及到了第三方組件的兼容性。
之前在IOS上用的Carousel組件在Android會有一些異常的表現(xiàn)。解決方案有兩種:

    1. 修改組件源碼,修復(fù)異常;
    1. 用一個兼容性沒問題的同類組件替換

在解決過程中兩種辦法都嘗試過,都可行。從這里也獲取一個經(jīng)驗,之后在選擇三方庫的時候,盡量選擇更新時間近、star數(shù)量高、仍在維護、大廠出品的。

7. 監(jiān)聽物理回退

由于安卓機子有一個物理回退鍵,如果在RN項目中不對其處理,則點擊物理回退鍵就會關(guān)閉App,而我們的預(yù)期是希望點擊后回退上一頁。

首頁我們要知道,點擊物理回退,其實會調(diào)用端的onBackPressed方法,所以我們需要判斷如果是RN頁面,應(yīng)該讓RN代碼自行決定處理方式,當然這層邏輯其實初始化項目就做好了:

    @Override
    public void onBackPressed() {
        //super.onBackPressed();

        if(mReactInstanceManager != null){
            mReactInstanceManager.onBackPressed();
        }else{
            super.onBackPressed();
        }
    }

這樣我們只需要在RN項目里監(jiān)聽這個回退,然后處理自己想要的邏輯就行了,代碼大致如下:

    componentDidMount() {
        if (Platform.OS === 'android') {
            BackHandler.addEventListener('hardwareBackPress', this._handleBack.bind(this));
        }
    }

    componentWillUnmount() {
        if (Platform.OS === 'android') {
            BackHandler.removeEventListener('hardwareBackPress', this._handleBack.bind(this));
        }
    }

只需要在程序入口做一次監(jiān)聽,后續(xù)頁面無需處理。

8. Modal

Android平臺Modal組件中的onRequestClose是一個必傳參數(shù),IOS則不需要。
可以在Modal的文檔上可以看到關(guān)于onRequestClose參數(shù)的描述:

On the Android platform, this is a required function.

至于為什么只有安卓平臺需要,我猜大概率和物理回退的相關(guān)處理有關(guān)系。

9. 自定義字體的高度問題

目前項目中引入了兩個外部字體:思源宋和閱文定制的數(shù)字字體。
引入字體會有一定高度的上下pandding,樣式處理上也有別于常規(guī)字體,需要設(shè)置lineHeightheight更好的定位位置。

10. Text樣式之ellipsizeMode屬性

Text樣式中的ellipsizeMode屬性 , 用來配合numberOfLines 顯示不完全省略的位置, 可選值'head', 'middle','tail','clip',而其中'clip'只能在IOS中使用,安卓平臺會報錯。

11. popover組件

這個問題同問題6,一樣涉及到了第三方組件的兼容性。
其中比較核心的問題是安卓平臺上不支持shadow陰影屬性的設(shè)置,這個問題在下一條會提到。
另外這個庫的開發(fā)時間比較早且已經(jīng)無人維護,所以類似這樣的庫以后應(yīng)該規(guī)避。
至于最終的解決方案,其實是加了一層蒙層來替代陰影的效果。

12. 陰影屬性

在IOS上可以通過如下設(shè)置陰影:

    shadowOffset: {width: 0, height: 0},
    shadowColor: 'black',
    shadowOpacity: 1,
    shadowRadius: 5

而Android上并不支持shadow相關(guān)的屬性,只提供了一個elevation屬性,使用方法如下:

    backgroundColor: 'black',
    elevation: 20,

elevation顧名思義就是 “仰角”,通過為視圖增加 “仰角” 方式來提供陰影,仰角越大,陰影越大。
elevation的設(shè)置比較局限,設(shè)置無法設(shè)置offset。如果需要更好的效果,還是需要通過其它方式去實現(xiàn),svg、漸變等,當然也有這樣庫提供了解決方案,像react-native-shadow、react-native-cardview都是值得參考的。

13. 觸摸點擊

目前關(guān)于觸摸點擊有以下幾種方式:

  • TouchableHighlight

? What it does: Darkens or lightens the background of the element when pressed.
? When to use it: On iOS for touchable elements or buttons that have a solid shape or background, and on ListView items.

  • TouchableOpacity

? What it does: Lightens the opacity of the entire element when pressed.
? When to use it: On iOS for touchable elements that are standalone text or icons with no backgroundcolor.

  • TouchableNativeFeedback

? What it does: Adds a ripple effect to the background when pressed.
? When to use it: On Android for almost all touchable elements.

安卓平臺推薦用TouchableNativeFeedback

14. TextInput

TextInput在安卓平臺默認有下劃線且框內(nèi)文字樣式也有問題,需要做如下兼容處理:

    underlineColorAndroid = "transparent"  //android需要設(shè)置下劃線為透明才能去掉下劃線
    style={{padding:0}}// 矯正樣式

15. ScrollView

我們觀察Android和IOS默認的下拉刷新表現(xiàn)形式是不一樣的,這是因為安卓上的ScrollView沒有IOS的彈性bounces,這也使得我們通過onScrollonScrollEndDrag獲取X軸、Y軸距離做的一些判斷會有所區(qū)別。

16. react-native-scrollable-tab-view組件卡頓

這個組件在切換兩個數(shù)據(jù)量稍大的Tab時,就會有明顯的卡頓,開始以為是性能問題導(dǎo)致動畫卡頓,后來debug發(fā)現(xiàn)是組件在切換回已經(jīng)render的view,還做了一次render,導(dǎo)致阻塞了動畫的執(zhí)行,解決辦法是通過shouldComponentUpdate判斷是否有必要render,當然也可以使用PureComponent來實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容