1. 程式人生 > >React Native入門——佈局實踐:開發京東客戶端首頁(二)TabBar的構建

React Native入門——佈局實踐:開發京東客戶端首頁(二)TabBar的構建

上篇文章講到構建京東客戶端首頁的搜尋欄,本篇我們一起來學習TabBar的構建。

根據之前的調研,在構建TabBar的方式上,我推薦使用國外大神James Ide(https://github.com/ide)釋出在Exponent上的react-native-tab-navigator(https://github.com/exponentjs/react-native-tab-navigator),這位大神封裝的控制元件簡單易用,而且更新速度還是跟得上的,甚至使用了一些ES7語法,同時他回覆ISSUE的速度也很不錯,我就問過他一個問題,過了一會兒就回復了。

不說那麼多了,首先來看一下TabBar的效果和佈局分析吧:


TabBar的外層為一個View(水平排布),內部為5個組合圖示,當選中時,切換相關頁面,TabBar按鈕呈現紅色,非選中時呈現白色,這些圖示也是已有UI切好的圖,所以邏輯處理比較簡單,主要控制好效果即可。

1.引入react-native-tab-navigator

我們可以在當前工程目錄下,使用npm i react-native-tab-navigator --save引入tab庫,目前最新版本為0.2.15


接著,我們在MainScreen類中將Tab控制元件import進來,具體程式碼如下:

import TabNavigator from 'react-native-tab-navigator';

export default class MainScreen extends Component {
    render() {
        return (
            <View style={{flex:1}}>
                <Header />
                <TabNavigator>
                    
                </TabNavigator>
            </View>
        );
    }
}

2.TabNavigator的樣式設定

上面的程式碼當中,TabNavigator繼承於View類,除了包括style的一些屬性可以和View控制元件一樣設定外,它還具有其他一些獨特的屬性,用於控制樣式

sceneStyle:場景樣式,即Tab頁容器的樣式,可按View的style設定

tabBarStyle:TabBar的樣式,基本也可按照普通的style寫法進行設定

tabBarShadowStyle:TabBar陰影的樣式,不過對於扁平化的設計,這個屬性應該用處不大

hidesTabTouch:bool型別,即是否隱藏Tab按鈕的按下效果

根據我們上面對TabBar樣式的分析,我們可以按照如下樣式,為TabNavigator指定tabBarStyle

const styles = StyleSheet.create({
    tab: {
        height: 52,
        backgroundColor: '#333333',
        alignItems: 'center'
    }
});
此時我們可以先執行在模擬器上看下效果

可以看到高度和背景色已經是我們想要的效果了,接下來,我們就可以著手構建Tab的Item了。

3.Item的構建

TabNavigator的Item就是我們所看到的5個Tab按鈕以及它們所對應的頁面,這些頁面在Android中可能以Fragment呈現,在iOS中可能以UIView呈現,而在React Native中,則是一個<View>,我們可以自己義,也可以直接放置其他控制元件。

這些Item在TabNavigator中,以<TabNavigator.Item>形式呈現,其可設定的相關屬性如下:

renderIcon: 必填項,即圖示,但為function型別,所以這裡需要用到Arrow Function
renderSelectedIcon: 選中狀態的圖示,非必填,也是function型別
badgeText: 即Tab右上角的提示文字,可為String或Number,類似QQ中Tab右上角的訊息提示,非必填
renderBadge: 提示角標渲染方式,function型別,類似render的使用,非必填
title: 標題,String型別,非必填
titleStyle: 標題樣式,style型別,非必填
selectedTitleStyle: 選中標題樣式,style型別,非必填
selected: bool型,是否選中狀態,可使用setState進行控制,預設false
onPress: function型,即點選事件的回撥函式,這裡需要控制的是state,而切換頁面已經由控制元件本身幫我們實現好了
allowFontScaling: bool型,是否允許字型縮放,預設false

而對於我們所關心的頁面切換,在TabNavigator.Item中,可將其置於<TabNavigator.Item>{<View/>}</TabNavigator.Item>之中,即作為Item的子元素存在,這裡請注意:如果添加了一個Item,必須為其新增一個View,否則將無法執行!

接著,我們將相關的圖示匯入工程中,具體方法在上一篇部落格中已經介紹,這裡不再贅述。

為了程式碼的簡潔,我們可以設計一個TabItem的渲染函式_renderTabItem

這個函式可以為我們建立Item,所以我們必須提供圖片資源(包括選中狀態)、Tag(區分Tab)、子元素View,那麼函式程式碼就可以寫成如下形式:

    _renderTabItem(img, selectedImg, tag, childView) {
        return (
            <TabNavigator.Item
                selected={this.state.selectedTab === tag}
                renderIcon={() => <Image style={styles.tabIcon} source={img}/>}
                renderSelectedIcon={() => <Image style={styles.tabIcon} source={selectedImg}/>}
                onPress={() => this.setState({ selectedTab: tag })}>
                {childView}
            </TabNavigator.Item>
        );
    }
這裡提醒大家:

如果使用本地圖片,即在<Image>中,source屬性內使用require的形式引用圖片,由於js本身的性質,不可以使用動態的require,而應該直接require後的圖片資源當做引數傳遞!而使用uri形式獲取線上資源不受影響

在上面的程式碼中,由於TabBar控制元件的問題,我們可以在tabIcon樣式中,控制Icon的上邊距,以達到居中的效果,程式碼如下:

    tabIcon: {
        width: 30,
        height: 35,
        resizeMode: 'stretch',
        marginTop: 10
    }
根據我們設計的函式,我們現在就可以方便地建立Tab了:
                <TabNavigator hidesTabTouch={true} tabBarStyle={styles.tab}>
                    {this._renderTabItem(HOME_NORMAL, HOME_FOCUS, HOME, this._createChildView(HOME))}
                    {this._renderTabItem(CATEGORY_NORMAL, CATEGORY_FOCUS, CATEGORY, this._createChildView(CATEGORY))}
                    {this._renderTabItem(FAXIAN_NORMAL, FAXIAN_FOCUS, FAXIAN, this._createChildView(FAXIAN))}
                    {this._renderTabItem(CART_NORMAL, CART_FOCUS, CART, this._createChildView(CART))}
                    {this._renderTabItem(PERSONAL_NORMAL, PERSONAL_FOCUS, PERSONAL, this._createChildView(PERSONAL))}
                </TabNavigator>
這裡說明幾點:

1.特別注意:由於在onPress函式中呼叫了this.setState,所以必須在類的使用建構函式,並對state進行初始化:

    constructor(props) {
        super(props);
        this.state = {selectedTab: HOME}
    }
2._createChildView的僅僅為了區分Tab的切換,以後需要換成不同的View,這裡給出程式碼:
    _createChildView(tag) {
        return (
            <View style={{flex:1,backgroundColor:'#00baff',alignItems:'center',justifyContent:'center'}}>
                <Text style={{fontSize:22}}>{tag}</Text>
            </View>
        )
    }


此時,我們的Tab也就基本構建完成了,我們可以在模擬器或真機上運行了!
看看效果,是不是還是比較滿意的呢?

相關推薦

React Native入門——佈局實踐開發京東客戶TabBar構建

上篇文章講到構建京東客戶端首頁的搜尋欄,本篇我們一起來學習TabBar的構建。根據之前的調研,在構建TabBar的方式上,我推薦使用國外大神James Ide(https://github.com/ide)釋出在Exponent上的react-native-tab-navig

React Native佈局實踐開發京東客戶——功能按鈕及控制元件封裝

從我寫第一篇React Native文章以來,我們幾乎是把所有的程式碼都放在一個js檔案中實現的,隨著工程複雜度的增加,各種自定義控制元件的程式碼就和業務邏輯程式碼耦合嚴重,這篇文章就來解決這一問題,讓我們一起來學習控制元件封裝的方法。1.明確需求首頁功能按鈕由一個圖片、一行

Python編程入門實踐——【作業】——第十四章記分

wid ont elif pac rom ext splay 添加 能夠 第十四章 14-1 按P開始新遊戲 : 鑒於遊戲《外星人入侵》 使用鍵盤來控制飛船, 最好讓玩家也能夠通過按鍵來開始遊戲。 請添加讓玩家在按P時開始遊戲的代碼。 也許這樣做會有所幫助: 將check_

機器學習入門之四機器學習的方法-神經網絡轉載

轉載 bsp 圖像 src nbsp 加速 數值 str 我們   轉自 飛鳥各投林   神經網絡      神經網絡(也稱之為人工神經網絡,ANN)算法是80年代機器學習界非常流行的算法,不過在90年代中途衰落。現在,攜著“深度學習”之勢,神

【Android開發—智能家居系列】用手機對WIFI模塊進行配置

名稱 ash 端口 clas 方式 mac class 二階 target 【Android開發—智能家居系列】(二):用手機對WIFI模塊進行配置 http://blog.csdn.net/u010924834/article/details/4949672

STM32開發筆記48STM32F4+DP83848乙太網通訊指南系列系統時鐘

本章為系列指南第二章,主要是介紹一下STM32F4的時鐘配置。時鐘是一個嵌入式產品從零開始開發的基石,一切邏輯都在時鐘的節奏中安靜地彈奏著,時鐘為整個電路帶來了歡快的「心跳」。開發者如果對時鐘沒有控制能力,就會把脈不準整個旋律的節奏,從而導致諸如通訊波特率、通訊時序、延時操作等關鍵功能全都紊亂,系統

Spring Cloud 入門教程(五) Ribbon實現客戶的負載均衡

接上節,假如我們的Hello world服務的訪問量劇增,用一個服務已經無法承載, 我們可以把Hello World服務做成一個叢集。  很簡單,我們只需要複製Hello world服務,同時將原來的埠8762修改為8763。然後啟動這兩個Spring Boot應用, 就可

用函數式編程,從0開發3D引擎和編輯器函數式編程準備

cat null 存在 處理程序 字符串 優勢 attr 互轉 defined 大家好,本文介紹了本系列涉及到的函數式編程的主要知識點,為正式開發做好了準備。 函數式編程的優點 1.粒度小 相比面向對象編程以類為單位,函數式編程以函數為單位,粒度更小。 正所謂: 我只想要

Scala入門到精通——第二十節 類型參數

ger 直觀 implicit 有時 com 方法調用 錯誤 println there 本節主要內容 Ordering與Ordered特質 上下文界定(Context Bound) 多重界定 類型約束 1. Ordering與Ordered

【Java入門提高篇】Day5 Java中的回調

彈出對話框 java入門 也會 color 編程 args performed show clas   Java中有很多個Timer,常用的有兩個Timer類,一個java.util包下的Timer,一個是javax.swing包下的Timer,兩個Timer類都有用到回調

生物特征識別小面積指紋識別算法

dpi 如果 mage 卷積 噪聲 狀態 AMM 計算 log 算法(一)已經介紹了一種小面積指紋識別算法可選的方案,是一種經典的方案,對於面積足夠大且level2特征高於最小限制時,為一種低內存占用,快速的實現方法。但在某些應用場中中(比如終端中,要求占用面積較小,且面

實測 《Tensorflow實例利用LSTM預測股票每日最高價》的結果

直接 batch Language name 開盤 num 完全 tor 運行 近期股市行情牛轉熊,大盤一直下探!由3200跌到了2700,想必很多人被深套了。這時想起人工智能能否預測股市趨勢?RNN能否起作用?   這時便從網上找下教程,發現網上有個例子,

嵌入式軟體開發 必須掌握的知識點有錯還望指點^_^

1、 嵌入式系統的主要組成部分 1)硬體裝置;2)嵌入式作業系統;3)應用軟體; 2、一條語句實現“判斷一個數X為2的 n 次冪” if(x&(x-1)==0) { } 3、linux系統的裝置分類 1)字元裝置;2)塊裝置

兄弟連區塊鏈入門教程eth原始碼分析p2p-udp.go原始碼分析

ping方法與pending的處理,之前談到了pending是等待一個reply。 這裡通過程式碼來分析是如何實現等待reply的。pending方法把pending結構體傳送給addpending. 然後等待訊息的處理和接收。 // ping sends a ping message to the giv

【python】爬蟲篇python對於html頁面的解析

我,菜雞,有什麼錯誤,還望大家批評指出!! 前言: 根據自己寫的上一篇文章,我繼續更第二部分的內容,詳情請點選如下連結 【python】爬蟲篇:python連線postgresql(一):https://blog.csdn.net/lsr40/article/details/833118

用Django框架開發一個簡單的企業網站

現在已經搭建好了網站的基本框架,繼續完善後臺功能,既然要寫後臺,自然要準備好資料庫。 資料庫我選擇熟悉的mysql,用的navicat視覺化管理工具,這裡我建立了一個my_web的資料庫;建立好資料庫後在專案目錄下的settings.py檔案內配置資料庫連線資訊: DATABASE

微信小程式text文字的展開與收起

之前寫過一篇《微信小程式:text文字的展開與收起》,通過css控制最大顯示行數,後來不少人私信問如果不足三行如何自動隱藏“展開/收起”按鈕;我接觸這個時間比較短,也不太熟悉,暫時只能想到改為js控制文字長度來處理。

docker進階自定義映象、網路架構

一、製作自定義映象(docker commit) 要求:基於centos映象使用commit建立新的映象檔案。 1、使用映象啟動容器 在該容器基礎上修改yum源 [[email protected] docker_images]# docker run

讀書筆記Android中的程序間通訊

閱讀的書籍:《Android開發藝術探索》 關鍵詞:Serializable,Parcelable,Serializable和Parcelable的區別,Binder Serializable介面:java提供的一個序列化介面,為物件提供標準的序列化和反序列化操作

RabbitMQ入門及常用的5種模式的簡單使用

RabbitMQ是一個非常常用也非常強大的訊息中介軟體,主要用於應用與應用之間的通訊,有五種常見的使用方式,分別是:簡單模式,工作模式,釋出訂閱模式,路由模式以及萬用字元模式,這裡主要是路由模式的三種具