這篇記錄下tabbar+navigation的方式切換頁(yè)面
所屬關(guān)系:TabNavigator-> TabNavigator.Item-> Navigator-> component(頁(yè)面)
所有代碼都在這里了兴垦,注釋的也很清楚
/**
* Created by mymac on 2017/3/31.
* 創(chuàng)建tabbar,子試圖是Navigator
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
Image,
StatusBar,
} from 'react-native';
import TabNavigator from 'react-native-tab-navigator'
import FirstPage from './FirstPage'
import SecondPage from './SecondPage'
import ThirdPage from './ThirdPage'
import FourPage from './FourPage'
/* StatusBar的屬性
* 1.animated bool 進(jìn)行設(shè)置當(dāng)狀態(tài)欄的狀態(tài)發(fā)生變化的時(shí)候是否需要加入動(dòng)畫拳魁。當(dāng)前該動(dòng)畫支持backgroundColor,barStyle和hidden屬性
2.hidden bool 進(jìn)行設(shè)置狀態(tài)欄是否隱藏
3.backgroundColor color類型棵介,僅支持Android設(shè)備灯帮,設(shè)置狀態(tài)欄的背景顏色
4.translucent bool類型沉唠,僅支持Android設(shè)備, 進(jìn)行設(shè)置狀態(tài)欄是否為透明。當(dāng)狀態(tài)欄的值為true的時(shí)候妹田,應(yīng)用將會(huì)在狀態(tài)欄下面進(jìn)行繪制顯示贬丛。這樣在Android平臺(tái)上面就是沉浸式的效果撩银,可以達(dá)到Android和iOS應(yīng)用一致性效果。該值常常配置半透明效果的狀態(tài)欄顏色一起使用
5.barStyle enum('default','light-content') 枚舉類型豺憔,僅支持iOS設(shè)備额获。進(jìn)行設(shè)置狀態(tài)欄文字的顏色
6.networkActivityIndicatorVisible bool類型够庙,僅支持iOS設(shè)備。設(shè)置狀態(tài)欄上面的網(wǎng)絡(luò)進(jìn)度加載器是否進(jìn)行顯示
7.showHideTransition enum('fade','slide') 枚舉類型抄邀,僅支持iOS設(shè)備耘眨。進(jìn)行設(shè)置當(dāng)隱藏或者顯示狀態(tài)欄的時(shí)候的動(dòng)畫效果。默認(rèn)值為'fade'
* */
export default class HomePageNav extends Component {
constructor(props) {
super(props);
this.state = {
//默認(rèn)選擇第一個(gè)頁(yè)面('消息'默認(rèn)選擇第二個(gè)頁(yè)面)
//this.setState({selectedTab:'首頁(yè)'}) 這個(gè)用于切換頁(yè)面
//selectedTab:'' ->為不同的值境肾,就切換對(duì)應(yīng)的頁(yè)面
selectedTab:'首頁(yè)',
};
}
//配置場(chǎng)景動(dòng)畫,可以返回上面的動(dòng)畫類型
configureScene(route) {
//其他頁(yè)面點(diǎn)擊按鈕跳轉(zhuǎn)方法傳入?yún)?shù)剔难,在這里通過route.type可以接收到,對(duì)參數(shù)進(jìn)行動(dòng)畫的判斷
console.log('route.type is ='+route.type);
console.log('route.name is ='+route.name);
if (route.type == 'normal'){
return Navigator.SceneConfigs.PushFromRight
}
return Navigator.SceneConfigs.FloatFromRight
//直接用同一個(gè)動(dòng)畫跳轉(zhuǎn)
//return Navigator.SceneConfigs.FloatFromRight
}
//渲染
renderScene(route, navigator) {
//導(dǎo)航條跳轉(zhuǎn)傳遞參數(shù) params 為傳遞的參數(shù) 其他頁(yè)面?zhèn)髦禃r(shí)的名字要和這里設(shè)置的一樣
return <route.component {...route.params} navigator={navigator}/>
//沒有參數(shù)
// return <route.component navigator={navigator} />
}
/*
* 創(chuàng)建Navigator
* component:Navigator管理的視圖
* return:Navigator
* */
creatNavigator (component){
return (
<Navigator
initialRoute={{ name: component, component: component }}//默認(rèn)加載的頁(yè)面
configureScene={this.configureScene}
renderScene={this.renderScene}
style={{flex:1}}
navigationBar={
<Navigator.NavigationBar style={HomePageNavStyle.navStyleBase}
routeMapper={NavigationBarRouteMapper}/>}
/>
)
}
/*
* 創(chuàng)建tabbarItem
* showtitle:標(biāo)題
* index:第幾個(gè)
* 子視圖:Navigator
* return:tabbarItem
* */
CreatTabNavigatorItem (showtitle ,index ,normalImage , selectImage){
let subview = {}
switch (index){
case 1:
subview=this.creatNavigator(FirstPage);
break;
case 2:
subview=this.creatNavigator(SecondPage);
break;
case 3:
subview=this.creatNavigator(ThirdPage);
break;
case 4:
subview=this.creatNavigator(FourPage);
break;
}
return(
/*TabNavigator.Item 屬性
* renderIcon: 必填項(xiàng)奥喻,即圖標(biāo)偶宫,但為function類型,所以這里需要用到Arrow Function
renderSelectedIcon: 選中狀態(tài)的圖標(biāo)环鲤,非必填纯趋,也是function類型
badgeText: 即Tab右上角的提示文字,可為String或Number冷离,類似QQ中Tab右上角的消息提示吵冒,非必填
renderBadge: 提示角標(biāo)渲染方式,function類型西剥,類似render的使用痹栖,非必填
title: 標(biāo)題,String類型瞭空,非必填
titleStyle: 標(biāo)題樣式揪阿,style類型,非必填
selectedTitleStyle: 選中標(biāo)題樣式匙铡,style類型图甜,非必填
selected: bool型碍粥,是否選中狀態(tài)鳖眼,可使用setState進(jìn)行控制,默認(rèn)false
onPress: function型嚼摩,即點(diǎn)擊事件的回調(diào)函數(shù)钦讳,這里需要控制的是state,而切換頁(yè)面已經(jīng)由控件本身幫我們實(shí)現(xiàn)好了
allowFontScaling: bool型枕面,是否允許字體縮放愿卒,默認(rèn)false
* */
<TabNavigator.Item
title={showtitle}
onPress={()=>{this.setState({selectedTab:showtitle})}}
selected={this.state.selectedTab === showtitle}
titleStyle={HomePageNavStyle.TBarTitleStyle}
selectedTitleStyle={HomePageNavStyle.TBarTitleSelectStyle}
renderIcon={() => {return <Image source={normalImage}/> }}
renderSelectedIcon={() => { return <Image source={selectImage}/> }}
/*
* 另一種寫法,如果又返回值潮秘,可以直接省去{return }
* renderIcon={() => <Image source={normalImage} />}
* renderSelectedIcon={() => <Image source={selectImage} />}
* */
>
{subview}
</TabNavigator.Item>
);
}
c
/*
* 創(chuàng)建tabbar
* return:返回4個(gè)item的tabbar
* */
CreatTabBarView () {
return(
<TabNavigator>
{this.CreatTabNavigatorItem('首頁(yè)',1 , require('./appImages/homepage@2x.png') ,require('./appImages/homepage_select@2x.png'))}
{this.CreatTabNavigatorItem('消息',2 , require('./appImages/message@2x.png'), require('./appImages/message_select@2x.png'))}
{this.CreatTabNavigatorItem('朋友',3 , require('./appImages/friend@2x.png'), require('./appImages/friend_select@2x.png'))}
{this.CreatTabNavigatorItem('我的',4 , require('./appImages/mine@2x.png'),require('./appImages/mine_select@2x.png') )}
</TabNavigator>
);
}
render() {
return (
<View style={HomePageNavStyle.viewStyle}>
{this.CreatTabBarView()}
<StatusBar barStyle={'light-content' }/>
</View>
);
}
}
//切換tabbar時(shí)琼开,修改對(duì)應(yīng)的Navigator的標(biāo)題
let getNavigatorTitle = (route) => {
let NavigatorTitle;
switch (route.component.name){
case 'FirstPage':
NavigatorTitle = '首頁(yè)'
break;
case 'SecondPage':
NavigatorTitle = '消息'
break;
case 'ThirdPage':
NavigatorTitle = '朋友'
break;
case 'FourPage':
NavigatorTitle = '我的'
break;
}
return (
<View>
<Text style={HomePageNavStyle.navTitleStyle}>
{NavigatorTitle}
</Text>
</View>
);
}
//創(chuàng)建Navigator的標(biāo)題、左按鈕枕荞、右按鈕
var NavigationBarRouteMapper = {
// 標(biāo)題
Title(route, navigator, index, navState) {
return (
getNavigatorTitle(route)
);
},
// 左鍵
LeftButton(route, navigator, index, navState) {
if (index > 0) {
return (
<View>
<TouchableOpacity
underlayColor='transparent'
onPress={() => {
if (index > 0) {
navigator.pop()
}
}}>
<Text style={HomePageNavStyle.navLeftButtonStyle}>
返回
</Text>
</TouchableOpacity>
</View>
);
} else {
return null;
}
},
RightButton(route, navigator, index, navState) {
if (route.onPress)
return (
<View>
<TouchableOpacity
onPress={() => route.onPress()}>
<Text style={HomePageNavStyle.navRightButtonStyle}>
right
</Text>
</TouchableOpacity>
</View>
);
},
};
var HomePageNavStyle = StyleSheet.create({
viewStyle:{
flex:1,
},
TBarTitleStyle:{
color:'black',
},
TBarTitleSelectStyle:{
color:'red',
},
textStyleBase:{
marginTop:40,
marginHorizontal:20,
color:'red',
textAlign:'center',
},
navStyleBase:{
backgroundColor:'blue',
},
navTitleStyle:{
color:'white',
textAlign:'center',
flex:1,
fontSize:18,
fontWeight:'bold',
marginVertical:5,
},
navLeftButtonStyle:{
color:'white',
marginLeft:10,
fontSize:15,
marginTop:5,
},
navRightButtonStyle:{
color:'black',
marginRight:10,
fontSize:15,
},
});
AppRegistry.registerComponent('myTabBarAndNavigationTest', () => HomePageNav);
有一個(gè)需要注意的地方
切換tabbar時(shí)柜候,導(dǎo)航條的title改變搞动,這里需要說一下,在使用導(dǎo)航條的情況下渣刷,每次顯示一個(gè)頁(yè)面都會(huì)走
//創(chuàng)建Navigator的標(biāo)題鹦肿、左按鈕、右按鈕
var NavigationBarRouteMapper = {
// 標(biāo)題
Title(route, navigator, index, navState) {
return (
getNavigatorTitle(route)
);
},
};
這個(gè)方法辅柴,Title里面有四個(gè)參數(shù)箩溃,我們需要route這個(gè)參數(shù)
它有一個(gè)component屬性,component有一個(gè)name屬性碌嘀,
這個(gè)name的值就是這個(gè)頁(yè)面類名
例:
export default class FirstPage extends Component {
name的值就是FirstPage
就可以知道當(dāng)前是哪個(gè)類了涣旨,知道了哪個(gè)類,就可以設(shè)置對(duì)應(yīng)的導(dǎo)航條Title了
tabbar.gif
項(xiàng)目地址:https://github.com/chjwrr/RN-tabbar-navigation