在上一篇文章當(dāng)中,我們學(xué)習(xí)了react-native-scrollable-tab-view的基本使用方式,包括基本Props的使用介紹等。我們知道官方為我們提供了兩種基本的Tab控制器樣式,DefaultTabBar和ScrollableTabBar。很多情況下,官方的樣式并不能滿足我們的需求(備注:官方的樣式是文字+下劃線的風(fēng)格),那么此時(shí)就需要我們自己來實(shí)現(xiàn)特定的樣式。
今天我們是react-native-scrollable-tab-view的下篇,本片文章的很多概念建立在上篇的基礎(chǔ)之上,還沒有閱讀過的朋友可以先去參考[React Native]react-native-scrollable-tab-view(入門篇)。
本文要實(shí)現(xiàn)這樣的效果:

一、準(zhǔn)備工作
1.新建一個(gè)項(xiàng)目
react-native init Demo7
2.添加react-native-scrollable-tab-view
npm install react-native-scrollable-tab-view --save
3.添加react-native-vector-icons
> npm install react-native-vector-icons --save
> rnpm link
rnpm是一個(gè)React Native包管理器,我們也可以通過編輯android/app/build.gradle 添加下面的行達(dá)到同樣的目的:
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
一個(gè)“圖標(biāo)”庫,官方描述為‘3000 Customizable Icons for React Native with support for NavBar/TabBar/ToolbarAndroid, image source and full stying.’ 可見,這個(gè)庫為我們提供了很多圖標(biāo),如果你不想花費(fèi)時(shí)間去設(shè)計(jì)一些圖標(biāo),不妨使用這個(gè)庫來替代。
有趣的是,這個(gè)庫的圖標(biāo)來源有很多,下面大概列舉了一些:
-
Entypo
by Daniel Bruce (411icons) -
EvilIcons
by Alexander Madyankin & Roman Shamin (v1.8.0,70icons) -
FontAwesome
by Dave Gandy (v4.6.3,634icons) -
Foundation
by ZURB, Inc. (v3.0,283icons) -
Ionicons
by Ben Sperry (v3.0.0,859icons) -
MaterialIcons
by Google, Inc. (v2.2.3,932icons) -
Octicons
by Github, Inc. (v3.5.0,166icons) -
Zocial
by Sam Collins (v1.0,100icons)
其中用的最多的是Ionicons
,所以本篇文章的圖標(biāo)來源也就選擇它了。
另外,react-native-vector-icons的用法非常的多,我們今天只會(huì)用到3個(gè)基本屬性:
| 屬性 | 描述 | 默認(rèn)值 |
|---|---|---|
| size | 設(shè)置圖標(biāo)的大小 | 12 |
| name | 設(shè)置使用的圖標(biāo) | 無 |
| color | 設(shè)置圖標(biāo)的顏色 | 系統(tǒng)默認(rèn) |
其中,name就是你要使用的圖標(biāo)名稱,如果我們選擇Ionicons
,讓我們看下如何找到你需要的圖標(biāo),進(jìn)入Ionicons
,我們看到如下的界面

紅色區(qū)域輸入你想要的圖標(biāo)名稱(英文哈~),比如我們輸入
search,結(jié)果頁面如下
每個(gè)圖標(biāo),都提供了iOS、iOS-Outline、Material Design三種不同風(fēng)格的樣式,點(diǎn)擊結(jié)果中的某一行數(shù)據(jù),出現(xiàn)如下界面

紅色區(qū)域就是我們最終需要的圖標(biāo)的名稱,即
name的值。
二、開始工作
首先,自定義一個(gè)TabBar組件你需要知道以下幾個(gè)點(diǎn):
添加必要屬性到組件中(必選)
propTypes = {
goToPage: React.PropTypes.func, // 跳轉(zhuǎn)到對(duì)應(yīng)tab的方法
activeTab: React.PropTypes.number, // 當(dāng)前被選中的tab下標(biāo)
tabs: React.PropTypes.array, // 所有tabs集合
}-
實(shí)現(xiàn)
setAnimationValue(可選,如果你需要在tab切換的時(shí)候有動(dòng)畫效果)
setAnimationValue({value}) {} render方法需要返回一個(gè)組件作為TabBar跟其他任何組件一樣,你可以傳遞自己的
props
好了,介紹完要點(diǎn),我們就開始編寫TabBar組件了。
1.新建一個(gè)WeixinTabBar.js文件,導(dǎo)入Ionicons
。
import Icon from 'react-native-vector-icons/Ionicons';
2.我們希望每個(gè)Tab的圖標(biāo)和名稱都是外部組件通過prop傳遞進(jìn)來,而不是內(nèi)部寫死,這樣有利于擴(kuò)展,所以我們添加兩個(gè)prop:tabNames和tabIconNames
propTypes = {
...
tabNames: React.PropTypes.array, // 保存Tab名稱
tabIconNames: React.PropTypes.array, // 保存Tab圖標(biāo)
}
3.實(shí)現(xiàn)render方法
render() {
return (
<View style={styles.tabs}>
{this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))}
</View>
);
}
這個(gè)方法很簡單,返回一個(gè)容器View,容器View內(nèi)包含的子View是通過遍歷tabs,調(diào)用renderTabOption方法來動(dòng)態(tài)生成的。
4.實(shí)現(xiàn)renderTabOption方法
renderTabOption(tab, i) {
const color = this.props.activeTab == i? "#6B8E23" : "#ADADAD"; // 判斷i是否是當(dāng)前選中的tab,設(shè)置不同的顏色
return (
<TouchableOpacity onPress={()=>this.props.goToPage(i)} style={styles.tab}>
<View style={styles.tabItem}>
<Icon
name={this.props.tabIconNames[i]} // 圖標(biāo)
size={30}
color={color}/>
<Text style={{color: color}}>
{this.props.tabNames[i]}
</Text>
</View>
</TouchableOpacity>
);
}
這個(gè)方法應(yīng)該也比較簡單,使用TouchableOpacity包裹兩個(gè)View:Icon和Text。
代碼分析:
---------------------------start---------------------------
首先,判斷i是否是當(dāng)前選中的activeTab,來使用不同的顏色,然后:
TouchableOpacity:點(diǎn)擊觸發(fā)onPress方法,使用goToPage跳轉(zhuǎn)到對(duì)應(yīng)的tab
Icon:設(shè)置name(圖標(biāo),使用tabIconNames[i]獲取),size(圖標(biāo)大小),color(圖標(biāo)顏色)
Text:設(shè)置文本(使用tabNames[i]獲?。琧olor(文字顏色)
---------------------------end---------------------------
5.使用WeixinTabBar
打開index.android.js文件,導(dǎo)入ScrollableTabView 和 WeixinTabBar
> import ScrollableTabView from 'react-native-scrollable-tab-view'
> import WeixinTabBar from './WeixinTabBar'
我們最終實(shí)現(xiàn)的效果圖有4個(gè)tab,所以這里定義兩個(gè)數(shù)組tabNames和tabIconNames,分別表示每個(gè)tab顯示的文字和圖片
constructor(props) {
super(props);
this.state = {
tabNames: ['Tab1', 'Tab2', 'Tab3', 'Tab4'],
tabIconNames: ['ios-paper', 'ios-albums', 'ios-paper-plane', 'ios-person-add'],
};
}
最后,實(shí)現(xiàn)render方法
render() {
let tabNames = this.state.tabNames;
let tabIconNames = this.state.tabIconNames;
return (
<ScrollableTabView
renderTabBar={() => <WeixinTabBar tabNames={tabNames} tabIconNames={tabIconNames}/>}
tabBarPosition='bottom'>
<View style={styles.content} tabLabel='key1'>
<Text>#1</Text>
</View>
<View style={styles.content} tabLabel='key2'>
<Text>#2</Text>
</View>
<View style={styles.content} tabLabel='key3'>
<Text>#3</Text>
</View>
<View style={styles.content} tabLabel='key4'>
<Text>#4</Text>
</View>
</ScrollableTabView>
);
}
其中renderTabBar使用我們自定義的WeixinTabBar。需要說明的是,即使我們不使用系統(tǒng)的DefaultTabBar和ScrollableTabBar,但tabLabel這個(gè)屬性必須使用,且值不能重復(fù)。
最后,感謝大家耐心看完本篇文章~
本文的源碼地址:Demo7