React-Native 之 項目實戰(一)

來源:互聯網
上載者:User
前言 本文有配套視頻,可以酌情觀看。 文中內容因各人理解不同,可能會有所偏差,歡迎朋友們聯絡我。 文中所有內容僅供學習交流之用,不可用於商業用途,如因此引起的相關法律法規責任,與我無關。 如文中內容對您造成不便,煩請聯絡 277511806@qq.com 處理,謝謝。 轉載麻煩註明出處,謝謝。

資料:連結: https://pan.baidu.com/s/1b3abwy 密碼: k8p5

源碼託管到 github 上,需要源碼的 點我下載,喜歡的話記得 Star,謝謝。 ES5轉ES6 關於ES6文法,建議大家可以看下阮老師的 ECMAScriot 6 快速瞭解的話,大家可以參考一下 es6文法快速上手 項目簡介 先來看下我們仿照的這款APP的效果:

從上圖中,我們可以看出複雜度並不大,但是時間關係我們盡量將所有的模組都做完,並完善細節。

譯註:

建議開啟 視頻 配合 文字 學習,以免有某些細節文中沒有提到,但以文中內容為準(根據反饋進行相應更新)

之所以選擇這款APP,和我個人的愛好有關,當然關鍵還是因為這個APP整體並不複雜,包含了市面上常見APP的樣式,並且很順利地就擷取到所有請求參數和圖片資源,很適合我們體驗 React-native 大致的開發流程。 項目分析

在開發APP前,產品經理大致會進行需求的分析,然後開會討論開發過程中需要使用到的技術、會遇到的痛點、分配相應任務、傾聽開發人員意見並進行相應的修改,最終確定整體原型圖、開發流程、技術、周期等等,當然其中還有UI的介入,我們沒有產品經理,UI也有現成的,所以大致給大家劃分以下幾塊:

需求分析:這款APP主要是通過抓取各大電商平台的 商品優惠資訊 進行篩選、分類並最終展現給使用者,使使用者可以方便、快捷、即時的擷取高品質的優惠資訊。

開發模型:我們這邊類似基於 原型模型 開發。

使用的技術:React-Native

功能模組:主要分為 首頁、海淘模組、小時風雲榜 三大模組等其它附屬模組(酌情增加)。

整體架構: 主體:由 TabBar 作為主體架構,以 首頁、海淘模組、小時風雲榜 為整體模組,根據 原型圖 的效果選擇相應的跳轉方式 資料展示:根據 原型圖 選擇相應的資料展示方式

命名規則:參考 編碼規範文檔(不同公司之間都有差異,具體看公司提供的文檔,這邊先遵守下面提到的規則即可)

測試:MDZZ,誰測試→→。 工程環境配置

所有需要用到的資源點擊下載。

首先,來配置 iOS 端。 將壓縮包內的 Images.xcassets 檔案夾直接替換掉我們iOS工程中的 Images.xcassets 檔案夾。 這時候我們可以看到所有圖片資源已經成功匯入到iOS工程中,接著我們點擊工程檔案進行一些必要的配置。 General —— App Icons and Launch Images —— 修改 Launch Images Source 為 Images.xcassets 檔案夾內的 LaunchImage ,清除 Launch Screen File 內容。 General —— Deployment Info —— Device Orientation —— 只保留 Portrait 選項。 開啟 info.plist 檔案,找到 Bundle name 選項,將其內容修改為 逛丟學習 開啟 info.plist 檔案,找到 App Transport Security Settings 選項,給其添加 Allow Arbitrary Loads 選項並設定內容為 YES (如果使用 IPV6標準 可以忽略這一步) OK,至此 iOS 端配置完畢。

接著,來配置 Android 端。 將壓縮包內的 drawable-xxhdpi 檔案夾複製粘貼到 GD/android/app/src/main/res/ 中。

設定 APP表徵圖 進入 GD/android/app/sec/ 開啟 AndroidManifest 檔案,修改 android:icon 項,如下:

    <applicatio>        android:icon="@drawable/icon"    </application>

設定 APP名稱 進入 GD/android/app/src/main/res/values/ 中,開啟 strings.xml 檔案,做如下修改:

    <resources>        <string name="app_name">逛丟學習</string>    </resources>
OK,至此 Android 配置完畢。

目錄結構與命名規則 為了方便理解,我們這邊先不按照常規的React-native開發結構進行開發,後續章節再慢慢轉變 這邊我們將檔案分為 main(入口)、home(首頁)、ht(海淘)、hourList(小時風雲榜) 4大部分,將相關的檔案放入對應的檔案夾,避免開發中頻繁切換文檔給新手帶來煩躁感 命名規則:
檔案夾命名方式我們就跟著 React-Native 預設的方式,採用 小寫 + 底線 進行命名 檔案命名方式我們採用 首碼(大寫) + 模組名稱(帕斯卡) 的方式進行命名 函數、常量、變數等使用 駝峰命名規則

目錄結構:

譯註: 駝峰命名規則:首字母小寫,後續單詞以大寫開頭,詳情點擊 駝峰命名 查看閱讀。 帕斯卡命名規則:和駝峰類似,只不過將首字母改為大寫,詳情點擊 帕斯卡命名 查看閱讀。 底線命名規則:就是使用底線分割單詞。 第三方架構

這邊來講下在 React-Native 中怎麼匯入第三方架構

首先,第三方架構肯定是要到 GitHub 找嘍。 在搜尋方塊內搜尋 react-native-tab-navigator 。 在下面的 說明 中告訴我們了,使用終端 —— 進到工程的主目錄下 —— 複製命令列()—— 斷行符號 —— 等待下載完成就匯入到工程中了。 到此,第三方架構匯入完成,使用在下面會提到。 主體架構搭建

上面提到使用 TabBar 作為主體架構,但是官方只提供了iOS端的 TabBarIOS ,時間原因為了加快開發進度,並且順帶講解 第三方架構使用 所以我們使用 <react-native-tab-navigator>進行開發

既然要使用架構,肯定要先引入架構檔案。

   // 引用第三方架構   import TabNavigator from 'react-native-tab-navigator';
根據 使用說明 文檔可以看出,使用方法和官方的 TabBarIOS 類似(不清楚的麻煩參考React Native 之 TabBarIOS和TabBarIOS.Item使用),所以我們把 三大模組 添加進TabBar,並且各個模組都是以 Navigator 的形式存在。
    export default class GD extends Component {    // ES6    // 構造      constructor(props) {        super(props);        // 初始狀態        this.state = {            selectedTab:'home',        };      }    // 返回TabBar的Item    renderTabBarItem(title, selectedTab, image, selectedImage, component) {        return(            <TabNavigator.Item                selected={this.state.selectedTab === selectedTab}                title={title}                selectedTitleStyle={{color:'black'}}                renderIcon={() => <Image source={{uri:image}} style={styles.tabbarIconStyle} />}                renderSelectedIcon={() => <Image source={{uri:selectedImage}} style={styles.tabbarIconStyle} />}                onPress={() => this.setState({ selectedTab: selectedTab })}>                    // 添加導航功能                <Navigator                        // 設定路由                    initialRoute={{                        name:selectedTab,                        component:component                    }}                    renderScene={(route, navigator) => {                        let Component = route.component;                        return <Component {...route.params} navigator={navigator} />                    }}                />            </TabNavigator.Item>        );    }    render() {        return (            <TabNavigator>                {/* 首頁 */}                {this.renderTabBarItem("首頁", 'home', 'tabbar_home_30x30', 'tabbar_home_selected_30x30', Home)}                {/* 海淘 */}                {this.renderTabBarItem("海淘", 'ht', 'tabbar_abroad_30x30', 'tabbar_abroad_selected_30x30', HT)}                {/* 小時風雲榜 */}                {this.renderTabBarItem("小時風雲榜", 'hourlist', 'tabbar_rank_30x30', 'tabbar_rank_selected_30x30', HourList)}            </TabNavigator>        );    }}const styles = StyleSheet.create({    container: {        flex: 1,        justifyContent: 'center',        alignItems: 'center',        backgroundColor: '#F5FCFF',    },    tabbarIconStyle: {        width:Platform.OS === 'ios' ? 30 : 25,        height:Platform.OS === 'ios' ? 30 : 25,    }});
至此,主體架構搭建完畢。

自訂導覽列樣式

從效果圖中可以看出,導覽列的樣式都差不多,因為我們前面已經設定了 Navigator ,這邊的話我們還需要自訂 Navigator 的樣式,可以看到所有的 Navigator 樣式都是相近的,所以這邊我們就抽出來,讓所有的 Navigator 共用一個組件就可以了。

那麼首先我們在 main 檔案夾中建立 GDCommunalNavBar 檔案並初始化一下裡面基本的內容

接著,我們來看下首頁的導覽列,首頁導覽列分別有左中右三個按鈕,左邊為半小時熱門,中間為點擊下拉顯示支援篩選的平台的列表,右邊則是商品搜尋,通常 Navigator 也只有這3個組件,為了使用者高度地自訂,這邊我們只在 currencyNavBar 中設定3個組件的布局,然後提供介面,擷取外部傳入的值,並在內部判斷是否需要建立相應的組件。

    export default class GDCommunalNavBar extends Component {    static propTypes = {        leftItem:PropTypes.func,        titleItem:PropTypes.func,        rightItem:PropTypes.func,    };    // 左邊    renderLeftItem() {        if (this.props.leftItem === undefined) return;        return this.props.leftItem();    }    // 中間    renderTitleItem() {        if (this.props.titleItem === undefined) return;        return this.props.titleItem();    }    // 右邊    renderRightItem() {        if (this.props.rightItem === undefined) return;        return this.props.rightItem();    }    render() {        return (            <View style={styles.container}>                {/* 左邊 */}                <View>                    {this.renderLeftItem()}                </View>                {/* 中間 */}                <View>                    {this.renderTitleItem()}                </View>                {/* 右邊 */}                <View>                    {this.renderRightItem()}                </View>            </View>        );    }}const styles = StyleSheet.create({    container: {        width:width,        height:Platform.OS === 'ios' ? 64 : 44,        backgroundColor:'white',        flexDirection:'row',        justifyContent:'space-between',        alignItems:'center',        borderBottomWidth:0.5,        borderBottomColor:'gray',        paddingTop:Platform.OS === 'ios' ? 15 : 0,    },});
這邊我們就已經完成了 Navigator 的樣式,我們到首頁來用一下,看好不好用,使用這邊就不說了(1.引用外部檔案;2. 首頁半小時熱門 這邊我們就先從 半小時熱門 開始,像這樣的資料展示,我們肯定是優先選擇 ListView ,其中, cell 的樣式分解如下:

我們先將資料請求下來,確定正確擷取到資料後,再來定義 cell 的樣式。

接下來我們來自訂一下 cell 樣式

    export default class GDCommunalNavBar extends Component {    static propTypes = {        image:PropTypes.string,        title:PropTypes.string,    };    render() {        return (            <View style={styles.container}>                {/* 左邊圖片 */}                <Image source={{uri:this.props.image}} style={styles.imageStyle} />                {/* 中間的文中 */}                <View>                    <Text numberOfLines={3} style={styles.titleStyle}>{this.props.title}</Text>                </View>                {/* 右邊的箭頭 */}                <Image source={{uri:'icon_cell_rightArrow'}} style={styles.arrowStyle} />            </View>        );    }}const styles = StyleSheet.create({    container: {        flexDirection:'row',        alignItems:'center',        justifyContent:'space-between',        backgroundColor:'white',        height:100,        width:width,        borderBottomWidth:0.5,        borderBottomColor:'gray',        marginLeft:15    },    imageStyle: {        width:70,        height:70,    },    titleStyle: {        width:width * 0.65,    },    arrowStyle: {        width:10,        height:10,        marginRight:30    }});
好了,到這裡 cell 樣式也定義完成並且效果是一樣的。
    export default class GDHalfHourHot extends Component {    // 構造      constructor(props) {        super(props);        // 初始狀態        this.state = {            dataSource: new ListView.DataSource({rowHasChanged:(r1, r2) => r1 !== r2}),        };        // 綁定        this.fetchData = this.fetchData.bind(this);      }    // 網路請求    fetchData() {        fetch('http://guangdiu.com/api/gethots.php')            .then((response) => response.json())            .then((responseData) => {                this.setState({                    dataSource: this.state.dataSource.cloneWithRows(responseData.data)                });            })            .done()    }    popToHome() {        this.props.navigator.pop();    }    // 返回中間按鈕    renderTitleItem() {        return(            <Text style={styles.navbarTitleItemStyle}>近半小時熱門</Text>        );    }    // 返回右邊按鈕    renderRightItem() {        return(            <TouchableOpacity                onPress={()=>{this.popToHome()}}            >                <Text style={styles.navbarRightItemStyle}>關閉</Text>            </TouchableOpacity>        );    }    // 返回每一行cell的樣式    renderRow(rowData) {        return(            <CommunalHotCell                image={rowData.image}                title={rowData.title}            />        );    }    componentDidMount() {        this.fetchData();    }    render() {        return (            <View style={styles.container}>                {/* 導覽列樣式 */}                <CommunalNavBar                    titleItem = {() => this.renderTitleItem()}                    rightItem = {() => this.renderRightItem()}                />                <ListView                    dataSource={this.state.dataSource}                    renderRow={this.renderRow}                    showsHorizontalScrollIndicator={false}                    style={styles.listViewStyle}                />            </View>        );    }}const styles = StyleSheet.create({    container: {        flex:1,        alignItems: 'center',    },    navbarTitleItemStyle: {        fontSize:17,        color:'black',        marginLeft:50    },    navbarRightItemStyle: {        fontSize:17,        color:'rgba(123,178,114,1.0)',        marginRight:15    },    listViewStyle: {        width:width,    }});

從效果圖中可以看出,我們還少了上面的提示標題,這邊很簡單,我們也來快速完成一些

    {/* 頂部提示 */}    <View style={styles.headerPromptStyle}>        <Text>根據每條折扣的點擊進行統計,每5分鐘更新一次</Text>    </View>

樣式部分:

    headerPromptStyle: {        height:44,        width:width,        backgroundColor:'rgba(239,239,239,0.5)',        justifyContent:'center',        alignItems:'center'    }

隱藏於顯示TabBar之通知的使用 配置TabBar隱藏與顯示條件

    // ES6    // 構造      constructor(props) {        super(props);        // 初始狀態        this.state = {            selectedTab:'home',            isHiddenTabBar:false,   // 是否隱藏tabbar        };      }   <TabNavigator                tabBarStyle={this.state.isHiddenTabBar !== true ? {} : {height:0, overflow:'hidden'}}                sceneStyle={this.state.isHiddenTabBar !== true ? {} : {paddingBottom:0}}            >                {/* 首頁 */}                {this.renderTabBarItem("首頁", 'home', 'tabbar_home_30x30', 'tabbar_home_selected_30x30', Home)}                {/* 海淘 */}                {this.renderTabBarItem("海淘", 'ht', 'tabbar_abroad_30x30', 'tabbar_abroad_selected_30x30', HT)}                {/* 小時風雲榜 */}                {this.renderTabBarItem("小時風雲榜", 'hourlist', 'tabbar_rank_30x30', 'tabbar_rank_selected_30x30', HourList)}            </TabNavigator>

這邊我們引入新的知識 —— 通知

使用通知很簡單,首先需要註冊通知並在適當的地方進行銷毀

    componentDidMount() {        // 註冊通知        this.subscription = DeviceEventEmitter.addListener('isHiddenTabBar', (data)=>{this.tongZhi(data)});    }    componentWillUnmount() {        // 銷毀        this.subscription.remove();    }
接著在我們需要的地方發送通知
    componentWillMount() {        // 發送通知        DeviceEventEmitter.emit('isHiddenTabBar', true);    }    componentWillUnmount() {        // 發送通知        DeviceEventEmitter.emit('isHiddenTabBar', false);    }

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.