標籤:關係 互動 manifest cdn type 根據 nop ons ber
本篇文章主要包括兩方面,如何從0開始把RN(react-native)項目整合進入現有Android項目,以及我們做的第一個RN的上線項目遇到的一些坑。
初次做RN項目,我們選擇做了一個邏輯相對簡單的轉轉app內部的協助中心項目。整個項目有4個頁面用的RN,其他頁面走的是native提供的統跳協議,跳轉到對應的native頁面或者是H5頁面。
整合RN到android項目中
react-native cli提供的init指令,可以協助我們建立一個RN的工程,但是很多情境下RN都是移植進入原生android或者iOS中。例如應該如何?,在Android頁面,點擊一個按鈕進入RN頁面呢?
下面是具體的實現過程。
1、建立一個Android項目
注意Minimum SDK選擇API23以上,一路next後finish。
2、添加JS
開啟studio的Terminal視窗,輸入如下命令:
npm init
會讓你輸入一些初始化package.json 的配置資訊,例如:
按照提示輸入就行了。
這一步完成之後,在項目的根目錄下就會產生package.json這個檔案,下一步輸入:
npm install [email protected] - -save
npm install [email protected]^0.44.0 - -save
注意,一定優先安裝react哦
大約一兩分鐘的樣子(如果卡到這裡了,看看安裝時是不是忘了配置鏡像),完成之後你的根目錄下會多了一個node_modules的檔案夾,裡面存放了下載好的React 和React Native。這裡有童鞋可能會質疑為什麼不把react和react-native的依賴直接寫入package.json中,然後直接npm install,如果這麼做的化,npm run start啟動的時候會報如下的錯誤:
接下來把如下命令粘貼到package.json 檔案下 scripts 標籤中
“start”: “node node_modules/react-native/local-cli/cli.js start”
下一步,在根目錄下建立index.android.js檔案並把如下代碼粘貼到其中:
代碼很簡單,置中顯示一個HelloWorld。
3、項目配置(Android)
用android studio開啟工程,修改android根目錄下Gradle Scripts的build.gradle(Module:app)檔案添加如下內容,注意下面appcompat-v7版本為25.2.0,而且我把dependencies中test相關的依賴移除掉了,避免不必要的bug。
在build.gradle(Project:***)中添加依賴
繼續下一步,在AndroidManifest.xml中添加網路存取權限
4、建立Activity
以下幾步不要安裝官網的去做,官網的步驟太麻煩,而且很久沒有更新了。
1.建立一個Activity,讓其繼承ReactActivity,並重寫getMainComponentName(),返回我們在index.android.js中註冊的HelloWorld這個組件。
別忘了把這個activity加入app/manifests/AndroidManifest.xml檔案中
2.自訂一個Application,繼承ReactApplication ,編寫以下代碼:
記得在AndroidManifest.xml中引用
android:name=”.App”
3.在目錄res/layout中增加activity_main.xml檔案,內容如下:
在MainActivity中通過按鈕啟動我們的ReactNativeActivity
4.app/src/main下建立assets檔案夾
運行如下命令
react-native start
然後直接在android studio工程中,點擊上方工具列的“run”按鈕,應該就可以了。
如果卡在了這一步:
沒關係,用資源管理員開啟你工程的根目錄,在此目錄下重新運行一個命令列並在其中輸入如下命令
react-native bundle - -platform android - -dev false - -entry-file index.android.js - -bundle-output app/src/main/assets/index.android.bundle - -assets-dest app/src/main/res/
完成之後assets目錄下會產生以下兩個檔案
確認一下react native service處於運行狀態,然後正常運行你的APP,點擊start,如果出現
恭喜你!你已經成功入坑,但是,實際項目中並不是這麼簡單!
項目實戰踩坑
1.技術棧
es6 + redux + react-redux + redux-thunk + react-navigation
2.項目心得這個項目踩坑最多的地方還是在react-navigation的使用上:
1、同一頁面參數不同,多次回退始終進入同一個頁面:
比如詳情頁頁面a/cateId/xy,當傳入不同cateId參數“cd”跳轉到同一詳情頁a/cateId/cd的時候,頁面是正常改變的,但是回退的時候,第一次是回到a/cateId/cd,再次回退還是回到a/cateId/cd。不會觸發頁面render。
stackNavigator導航管理的頁面,在切換的時候,不是按照堆棧的push,pop形式,而是通過移動指標到對應的頁面,同時標記此頁面為啟用狀態。
解決辦法是通過componentWillReceiveProps,shouldComponentUpdate以及componentDidUpdate,當nextProps中的params.cateId和當前的params.cateId不同的時候,觸發頁面的render。
2、實現手勢swipe向右滑動後退功能:
官方文檔介紹,react-navigation在根組件的navigationOptions設定中添加gesturesEnabled: true,就可以實現滑動切換切換頁面的需求,但是在真機上測試不生效。
通過讀源碼瞭解到,react-navigation內部是通過引入RN的PanResponder手勢識別系統來實現滑動的機制,只有在onMoveShouldSetPanResponder返回true的時候,才能執行接下來的手勢動作。具體執行方法如下:
因為上述代碼中的 GESTURE_RESPONSE_DISTANCE_HORIZONTAL 過小,導致始終return false,把這個值從20改到60就可以了。
3、實現頁面跳轉動畫效果
StackNavigator(RouteConfigs, StackNavigatorConfig);
在第二個參數StackNavigatorConfig的配置中,可以傳入mode: ‘card’,這個參數會在native端擷取預設的滑動效果,iOS端預設的是左右切換的效果,但是android端預設的是上下轉場效果。為了實現統一的過場效果。
幸好react-navigation提供了一個transitionConfig介面,可以實現定製化滑屏效果。不知道該如何定製嗎?沒有關係,源碼中已經在iOS端幫我們實現,稍微修改一下代碼就可以了。
FlatList問題:
1.ListHeaderComponent,ListFooterComponent
當FlatList有並列的組件的時候,會出現,其他並列的組件位置是固定的(類似於css中的position fixed),頁面只有FlatList地區是可以滾動的,為了實現這個頁面整體是可以滾動的,需要把FlatList上面的組件加入FlatList的ListHeaderComponent屬性中,同時把其下面的組件加入到ListFooterComponent中。
2.通過利用getItemLayout,把高度提前設定好,可以較少一次RN計算高度的render。
圖片問題:
1.RN中的圖片有兩種來源:native內部圖片,cdn的圖片。
native內部圖片,直接可以通過require圖片名字取到,一定不要加.png等尾碼。
例如:
當然我們可以通過在打包的時候把通過相對路徑引入的內部圖片,
例如:
通過配置–asset-dest打包進入native原生目錄res中,這時候要注意,打出來的RN的bundle,只有放入android的assets檔案夾下才能根據相對路徑取到這些存放在res目錄中的圖片。
cdn的圖片,只有指定圖片的寬高才能夠顯示出來。
與native互動的處理
NativeModules:native暴露出來的模組,可以通過NativeModules對象取到。
有些情境需要native直接傳遞某些參數到RN端,iOS可以通過調用initWithBundleURL,在initialProperties參數傳參,android通過getLaunchOptions把參數寫入返回的bundle中。在RN工程的根檔案(例如app.js),通過this.props.key(key是屬性名稱字)直接取到。
如果你喜歡我們的文章,關注我們的公眾號和我們互動吧。
React-native初體驗(安卓篇)