前段時間開始學習React Native,然后試著開始做一個小項目讶泰,在練手的同時,分享出來希望和各位同學互相學習react-native項目随珠。之前寫過項目相關的文章蝶俱,沒看過的同學可以參考一下:
- React-native項目入門與思考
- Flux, Reflux,Redux 學習與思考
- React native 項目入門(知乎日報,豆瓣電影侨把,[one]一個)
- React native 項目進階(redux, redux saga, redux logger)
React Native項目效果
目前項目完成了(One 【一個】)主體界面功能犀变,當然功能和原App還有較大的差距,之前主要對ios進行了適配秋柄,這兩天對Android也進行了一些調整获枝。有什么bug大家可以評論或者在github上提issue。先看一下效果圖:
這里貼的是ios的效果圖骇笔,android端的類似省店。接下來介紹項目的結構,用到的一些第三方庫笨触,以及項目過程中的小坑懦傍。
項目結構
- Pages
項目的主要界面,目錄下有One芦劣、Douban粗俱、Zhihu三個文件夾,分別對應one虚吟、豆瓣寸认、知乎日報三個應用,其中one是完成度相對比較高的串慰,其他兩個應用界面很少偏塞。 - Assets
目錄下存放了項目中用到了一些圖標,這里存放的是android和ios的共有圖標邦鲫,比如one主界面下面的四個圖標灸叼。android和ios的launch icon是在各自工程中分別設置的。 - Constants
定義項目中的常量 - Components
項目的一些自定義components掂碱,可以在多個pages中使用怜姿。 - Styles
定義常用的界面style,使用時可以直接引用疼燥,模擬android的styles沧卢,這樣就不需要在每個page中重復定義styles - Utils
定義常用的一些工具類,如網絡請求醉者、時間格式但狭、展示屬性等披诗。 - Actions
- reducers
- sagas
這三個目錄是redux相關的一些方法,相關的介紹可以查看 React native 項目進階(redux, redux saga, redux logger)立磁,當然閱讀之前最好有redux基礎呈队,推薦redux的學習教程:
http://leonshi.com/redux-saga-in-chinese/index.html
http://cn.redux.js.org/index.html
第三方庫
React Native 從第一次提交到現(xiàn)在已經有20個月的時間,目前github上有近4萬star唱歧,很多大牛貢獻了各種第三方庫宪摧,目前開始學習React Native對于新人初學者來說文檔和社區(qū)非常友好。這里羅列下用到的第三方庫:
"react-native-button": "github:ide/react-native-button",
"react-native-datepicker": "^1.3.2",
"react-native-drawer": "^2.2.2",
"react-native-fs": "^2.0.1-rc.2",
"react-native-root-toast": "^1.0.3",
"react-native-router-flux": "[3.30.1]",
"react-native-scrollable-tab-view": "0.6.0",
"react-native-sound": "^0.8.3",
"react-native-viewpager": "^0.2.1",
"react-redux": "^4.4.5",
"redux": "^3.6.0",
"redux-logger": "^2.6.1",
"redux-saga": "^0.11.1"
其中部分比較簡單颅崩,有些在之前的文章中進行了介紹几于,下面主要介紹:
"react-native-viewpager": "^0.2.1",
"react-native-scrollable-tab-view": "0.6.0",
"react-native-sound": "^0.8.3",
"react-native-fs": "^2.0.1-rc.2",
React-Native-ViewPager
是一個viewpager,one項目中的首頁沿后、文章頁沿彭、音樂頁均使用了viewpager,使用率很高尖滚,先看一個demo:
<ViewPager
dataSource={this.state.banners}
renderPage={this.renderBanners}
isLoop={true}
autoPlay={true}
/>
dataSource定義數(shù)據(jù)源喉刘,其數(shù)據(jù)源的定義過程是:
var bannerDataSource = new ViewPager.DataSource({
pageHasChanged: (p1, p2) => p1 !== p2,
});
banners: bannerDataSource.cloneWithPages([]),
renderPage用于展示每個pager的界面
renderBanners(data, pageID) {
return (
<Image style={{
height: 140,
width: deviceWidth,
}} source={{uri: data.cover}}>
</Image>
);
}
isLoop 是否輪播
autoPlay 是否自動播放
renderPageIndicator定義indicator的樣式 ,當然可以使用default的樣式漆弄,這里是一個示例睦裳,隱藏掉indicator:
renderPageIndicator={()=>(<View style={{width: 0, height: 0}}></View>)}
react-native-scrollable-tab-view
react-native-scrollable-tab-view用于定義應用的主tab,項目中主要定義了one的四個tab置逻,可以滑屏幕切換界面推沸,在項目中由于各個子界面自身有左右切換的需求,因此關閉了該功能券坞。
部分設置:
**renderTabBar
**
自定義tabbar,如項目中自定義了四個tab的樣式
**onChangeTab
**
當tab切換時回調
**locked
**
是否鎖定肺素,鎖定時不能左右滑動
**page
**
設置選中的tab
項目使用示例:
<ScrollableTabView initialPage={0} locked={true} prerenderingSiblingsNumber={1} tabBarPosition="bottom"
renderTabBar={()=><FacebookTabBar tabIcons={this.tabIcons}/>}>
<OneHome tabLabel="首頁"/>
<OneRead tabLabel="閱讀"/>
<OneMusic tabLabel="音樂"/>
<OneFilm tabLabel="電影"/>
</ScrollableTabView>
react-native-fs
react-native-sound
這兩個主要用于one音樂的播放恨锚,其中react-native-fs主要用于音樂的下載,react-native-sound用于本地文件的播放倍靡,這兩個庫都用到了原生方法猴伶,因此需要分別在android和ios項目中進行設置使用:
ios端
如圖需要Add兩個lib的*.xcodeproj到主工程的Libraries中,然后
如圖Add所有的*.a文件塌西,編譯運行就ok了他挎。
Android 端
- 在setting.gradle中添加:
include ':app'
include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
include ':RNSound', ':app'
project(':RNSound').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-sound/android')
- 在build.gradle中添加:
compile project(':react-native-fs')
compile project(':RNSound')
注意添加位置要正確,對代碼進行重新編譯捡需,在Android目錄機構下即可以看到RNSound办桨、react-native-fs兩個module。
兩個lib在react-native 中的使用比較簡單站辉,可以參考one項目中的使用:react-native-sound 和react-native-fs的使用
項目中踩坑
- Image中設置source={{url:"http://..."}}
在ios中這樣設置是沒有問題的呢撞,但是android中不起效, 需要設置source={{uri:"http://..."}},另關于Image损姜,目前必須設置width和height,官方解釋為防止在進行渲染時如果寬高不固定容易造成界面跳動殊霞,影響用戶體驗摧阅。 - react-native-sound 播放路徑問題
var whoosh = new Sound('whoosh.mp3', Sound.MAIN_BUNDLE, (error) => {
if (error) {
console.log('failed to load the sound', error);
} else { // loaded successfully
console.log('duration in seconds: ' + whoosh.getDuration() +
'number of channels: ' + whoosh.getNumberOfChannels());
}
});
其中'whoosh.mp3'為相對路徑,Sound.MAIN_BUNDLE為基本路徑绷蹲,在ios中可用棒卷,但是在android中提示找不到路徑,最終第一個參數(shù)設置絕對路徑祝钢,第二個參數(shù)設置為 '' 空串比规。
- react-native-sound 播放問題
musicHandler = new Sound(`${RNFS.DocumentDirectoryPath}/music.mp3`, '',(error) => {
if (error) {
console.log('failed to load the sound', error);
} else { // loaded successfully
this.playSound();
}
});
需要在sound創(chuàng)建成功的回調中啟動播放,不可以直接寫在創(chuàng)建的語句之后太颤。
4.gif圖問題
ios的Image支持直接播放gif圖苞俘,android需要添加lib,在build.gradle的dependencies中添加:
compile 'com.facebook.fresco:animated-gif:0.12.0'//for gif
5.布局問題
這種布局可以設置marginTop為負值即可龄章。
- 關于react-native-viewpager和react-native-srollable-tab-view嵌套問題
當發(fā)生嵌套時吃谣,可能發(fā)生界面的錯位,這是可以設置view的style:overflow: 'hidden'做裙,可以避免界面疊加錯位岗憋。
總結
目前項目中還有較多的問題,尤其是Android端锚贱,之后還會繼續(xù)進行完善仔戈。根據(jù)目前的開發(fā)體驗,感覺react native非常適合于展示類型的app拧廊,開發(fā)效率非常高监徘,但是在Android上體驗要低于ios,有很大的優(yōu)化空間吧碾。
接下來在繼續(xù)完善項目的基礎上凰盔,繼續(xù)學習相關的知識,爭取做出自己的東西倦春,實現(xiàn)在React-native項目入門與思考中立下的flag户敬。
推薦閱讀:
React-native項目入門與思考
React native 項目入門(知乎日報,豆瓣電影睁本,[one]一個)
React native 項目進階(redux, redux saga, redux logger)
React Native 項目2(One 【一個】客戶端)