React Native 專案(One 【一個】客戶端)

wutongke發表於2017-03-04

前段時間開始學習React Native,然後試著開始做一個小專案,在練手的同時,分享出來希望和各位同學互相學習react-native專案。之前寫過專案相關的文章,沒看過的同學可以參考一下:

目前專案完成了(One 【一個】)主體介面功能,當然功能和原App還有較大的差距,之前主要對ios進行了適配,這兩天對Android也進行了一些調整。有什麼bug大家可以評論或者在github上提issue。先看一下效果圖:

React Native 專案(One 【一個】客戶端)
Paste_Image.png

React Native 專案(One 【一個】客戶端)
Paste_Image.png

React Native 專案(One 【一個】客戶端)
Paste_Image.png

React Native 專案(One 【一個】客戶端)
Paste_Image.png

React Native 專案(One 【一個】客戶端)
Paste_Image.png

這裡貼的是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的學習教程:
    leonshi.com/redux-saga-…
    cn.redux.js.org/index.html

第三方庫

React Native 從第一次提交到現在已經有20個月的時間,目前github上有近4萬star,很多大牛貢獻了各種第三方庫,目前開始學習React Native對於新人初學者來說文件和社群非常友好。這裡羅列下用到的第三方庫:

    "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定義資料來源,其資料來源的定義過程是:

        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端

1.

React Native 專案(One 【一個】客戶端)

如圖需要Add兩個lib的*.xcodeproj到主工程的Libraries中,然後

2.

React Native 專案(One 【一個】客戶端)

如圖Add所有的*.a檔案,編譯執行就ok了。

Android 端

  1. 在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')複製程式碼
  2. 在build.gradle中新增:
     compile project(':react-native-fs')
     compile project(':RNSound')複製程式碼
    React Native 專案(One 【一個】客戶端)
    Paste_Image.png

注意新增位置要正確,對程式碼進行重新編譯,在Android目錄機構下即可以看到RNSound、react-native-fs兩個module。

兩個lib在react-native 中的使用比較簡單,可以參考one專案中的使用:react-native-sound 和react-native-fs的使用

專案中踩坑

  1. Image中設定source={{url:"http://..."}}
    在ios中這樣設定是沒有問題的,但是android中不起效, 需要設定source={{uri:"http://..."}},另關於Image,目前必須設定width和height,官方解釋為防止在進行渲染時如果寬高不固定容易造成介面跳動,影響使用者體驗。
  2. 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中提示找不到路徑,最終第一個引數設定絕對路徑,第二個引數設定為 '' 空串。
  3. 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建立成功的回撥中啟動播放,不可以直接寫在建立的語句之後。

4.gif圖問題
ios的Image支援直接播放gif圖,android需要新增lib,在build.gradle的dependencies中新增:

compile 'com.facebook.fresco:animated-gif:0.12.0'//for gif複製程式碼

5.佈局問題

React Native 專案(One 【一個】客戶端)
Paste_Image.png

這種佈局可以設定marginTop為負值即可。

  1. 關於react-native-viewpager和react-native-srollable-tab-view巢狀問題
    當發生巢狀時,可能發生介面的錯位,這是可以設定view的style:overflow: 'hidden',可以避免介面疊加錯位。

總結

目前專案中還有較多的問題,尤其是Android端,之後還會繼續進行完善。根據目前的開發體驗,感覺react native非常適合於展示型別的app,開發效率非常高,但是在Android上體驗要低於ios,有很大的優化空間。
接下來在繼續完善專案的基礎上,繼續學習相關的知識,爭取做出自己的東西,實現在React-native專案入門與思考中立下的flag。

專案地址請戳這裡

歡迎關注公眾號wutongke,每天推送移動開發前沿技術文章:

React Native 專案(One 【一個】客戶端)
wutongke

推薦閱讀:

React-native專案入門與思考
React native 專案入門(知乎日報,豆瓣電影,[one]一個)
React native 專案進階(redux, redux saga, redux logger)
React Native 專案2(One 【一個】客戶端)

相關文章