,首先來看一下TabBar的效果和佈局分析吧:react
TabBar的外層爲一個View(水平排布),內部爲5個組合圖標,當選中時,切換相關頁面,TabBar按鈕呈現紅色,非選中時呈現白色,這些圖標也是已有UI切好的圖,因此邏輯處理比較簡單,主要控制好效果便可。git
1.引入react-native-tab-navigatorgithub
咱們能夠在當前工程目錄下,使用npm i react-native-tab-navigator --save引入tab庫,目前最新版本爲0.2.15npm
接着,咱們在MainScreen類中將Tab控件import進來,具體代碼以下:react-native
1 import TabNavigator from 'react-native-tab-navigator'; 2 3 export default class MainScreen extends Component { 4 render() { 5 return ( 6 <View style={{flex:1}}> 7 <Header /> 8 <TabNavigator> 9 10 </TabNavigator> 11 </View> 12 ); 13 } 14 }
上面的代碼當中,TabNavigator繼承於View類,除了包括style的一些屬性能夠和View控件同樣設置外,它還具備其餘一些獨特的屬性,用於控制樣式ide
sceneStyle:場景樣式,即Tab頁容器的樣式,可按View的style設置函數
tabBarStyle:TabBar的樣式,基本也可按照普通的style寫法進行設置佈局
tabBarShadowStyle:TabBar陰影的樣式,不過對於扁平化的設計,這個屬性應該用處不大字體
hidesTabTouch:bool類型,便是否隱藏Tab按鈕的按下效果flex
根據咱們上面對TabBar樣式的分析,咱們能夠按照以下樣式,爲TabNavigator指定tabBarStyle
1 const styles = StyleSheet.create({ 2 tab: { 3 height: 52, 4 backgroundColor: '#333333', 5 alignItems: 'center' 6 } 7 });
此時咱們能夠先運行在模擬器上看下效果
能夠看到高度和背景色已是咱們想要的效果了,接下來,咱們就能夠着手構建Tab的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,那麼函數代碼就能夠寫成以下形式:
1 _renderTabItem(img, selectedImg, tag, childView) { 2 return ( 3 <TabNavigator.Item 4 selected={this.state.selectedTab === tag} 5 renderIcon={() => <Image style={styles.tabIcon} source={img}/>} 6 renderSelectedIcon={() => <Image style={styles.tabIcon} source={selectedImg}/>} 7 onPress={() => this.setState({ selectedTab: tag })}> 8 {childView} 9 </TabNavigator.Item> 10 ); 11 }
這裏提醒你們:
若是使用本地圖片,即在<Image>中,source屬性內使用require的形式引用圖片,因爲js自己的性質,不可使用動態的require,而應該直接require後的圖片資源當作參數傳遞!而使用uri形式獲取在線資源不受影響
在上面的代碼中,因爲TabBar控件的問題,咱們能夠在tabIcon樣式中,控制Icon的上邊距,以達到居中的效果,代碼以下:
1 tabIcon: { 2 width: 30, 3 height: 35, 4 resizeMode: 'stretch', 5 marginTop: 10 6 }
根據咱們設計的函數,咱們如今就能夠方便地建立Tab了:
1 <TabNavigator hidesTabTouch={true} tabBarStyle={styles.tab}> 2 {this._renderTabItem(HOME_NORMAL, HOME_FOCUS, HOME, this._createChildView(HOME))} 3 {this._renderTabItem(CATEGORY_NORMAL, CATEGORY_FOCUS, CATEGORY, this._createChildView(CATEGORY))} 4 {this._renderTabItem(FAXIAN_NORMAL, FAXIAN_FOCUS, FAXIAN, this._createChildView(FAXIAN))} 5 {this._renderTabItem(CART_NORMAL, CART_FOCUS, CART, this._createChildView(CART))} 6 {this._renderTabItem(PERSONAL_NORMAL, PERSONAL_FOCUS, PERSONAL, this._createChildView(PERSONAL))} 7 </TabNavigator>
這裏說明幾點:
1.特別注意:因爲在onPress函數中調用了this.setState,因此必須在類的使用構造函數,並對state進行初始化:
1 constructor(props) { 2 super(props); 3 this.state = {selectedTab: HOME} 4 }
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也就基本構建完成了,咱們能夠在模擬器或真機上運行了!
看看效果,是否是仍是比較滿意的呢?
源代碼及資源文件:https://github.com/yuanguozheng/JdApp
本次Commit:https://github.com/yuanguozheng/JdApp/commit/b661cd8767749bcf8512ea6564f4ac379adb5cf7