react-navigation使用
facebook前一段時(shí)間開始推薦使用react-navigation际跪,并且在0.44發(fā)布的時(shí)將之前一直存在的Navigator廢棄了商佛。解決導(dǎo)航卡頓,數(shù)據(jù)傳遞姆打,Tabbar和navigator布局良姆,支持redux。目前還在完善中幔戏。
react-navigation分為三個(gè)部分:
StackNavigator類似頂部導(dǎo)航條玛追,用來跳轉(zhuǎn)頁面和傳遞參數(shù)。
TabNavigator類似底部標(biāo)簽欄闲延,用來區(qū)分模塊痊剖。
DrawerNavigator抽屜,類似從App左側(cè)滑出一個(gè)頁面垒玲。目前是用不到陆馁。
第三方組件使用前要安裝:
NPM下安裝:
npm install --save react-navigation
Yarn安裝:
yarn add react-navigation
頂部導(dǎo)航的基本使用:
1.引入控件:
import { StackNavigator } from 'react-navigation';
2.創(chuàng)建第一個(gè)頁面:
class HomeScreen extends Component {
static navigationOptions = {
title: 'Home', // 頂部標(biāo)題
};
render() {
const { navigate } = this.props.navigation;
return (
<View>
<Text>Hello, Chat App!代碼控制臺(tái)</Text>
<Button
onPress={() => navigate('Chat')}
title="Go Chat"
/>
</View>
);
}
}
針對(duì)這個(gè)navigationOptions 屬性分析下(側(cè)滑菜單使用),
這個(gè)使用一般是在類里面:
title:通用標(biāo)題合愈,當(dāng)你不寫drawerLabel時(shí)叮贩,使用此參數(shù)作為側(cè)滑標(biāo)題,通常都不寫
drawerLabel:側(cè)滑標(biāo)題
drawerIcon:側(cè)滑的標(biāo)題圖標(biāo)想暗,這里會(huì)回傳兩個(gè)參數(shù),{focused: boolean, tintColor: string}帘不,focused表示是否是選中狀態(tài)说莫,tintColor表示選中的顏色,這個(gè)顏色是我們自己在根視圖定義的寞焙。當(dāng)然储狭,你也可以使用其他的組件來作為圖標(biāo),比如Text
如果有側(cè)滑菜單需要關(guān)閉可以直接調(diào)用,這里關(guān)閉的參數(shù)為DrawerClose,通過props屬性可以拿到當(dāng)前navigation捣郊,此外屬性名一定要寫成navigationOptions
<TouchableOpacity onPress={()=>{
//點(diǎn)擊關(guān)閉側(cè)滑
this.props.navigation.navigate('DrawerClose')
//打開側(cè)滑:
this.props.navigation.navigate('DrawerOpen')
}}>
<Text>關(guān)閉側(cè)滑欄</Text>
</TouchableOpacity>
3.創(chuàng)建要跳轉(zhuǎn)的頁面:
export class ChatScreen extends Component {
static navigationOptions = {
title: 'Chat',
};
render() {
return (
<View>
<Text>Chat with Lucy</Text>
</View>
);
}
}
4.寫一個(gè)頁面控制器:
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Chat: { screen: ChatScreen },
});
這樣就可以直接使用跳轉(zhuǎn)了
StackNavigator屬性深入分析
可以看到上面第四部的頁面控制器用到了 StackNavigator辽狈,這個(gè)組件才是使用中的重點(diǎn) 也是難點(diǎn)。
- 先看他的構(gòu)造:
StackNavigator(RouteConfigs, StackNavigatorConfig)
RouteConfigs:
它主要是來配置頁面路由的,和我們安卓的清單文件性質(zhì)差不多呛牲,主要是配置所有的頁面:
{
AAA:{
screen:FirstNavigation,
navigationOptions:({
title:'首頁'
})
},
BBB:{
screen:SecondNavigation,
navigationOptions:({navigation}) => ({
title: "第二個(gè)界面"
})
}
}
上面的navigationOptions 這個(gè)是配置屬性刮萌,可以不用再這里配置,一般這個(gè)都是在頁面去配置娘扩,對(duì)應(yīng)頁面需要什么屬性着茸,就配置什么壮锻。
navigationOptions 屬性分析下():
title: 這個(gè)即可以作為頭部標(biāo)題,也可以作為返回標(biāo)題和Tab標(biāo)題涮阔,如果設(shè)置了這個(gè)導(dǎo)航欄和標(biāo)簽欄的title就會(huì)變成一樣的猜绣,所以不推薦使用這個(gè)方法。
header: 自定義導(dǎo)航條敬特,系統(tǒng)的導(dǎo)航條會(huì)隱藏 這個(gè)屬性目前還有bug,需要隱藏可以設(shè)置為null
headerTitle: 標(biāo)題標(biāo)題掰邢,設(shè)置導(dǎo)航欄標(biāo)題,推薦用這個(gè)方法伟阔。
headerBackTitle: 回退標(biāo)題 這個(gè)沒有顯示出來
headerTruncatedBackTitle: 當(dāng)回退標(biāo)題不能顯示的時(shí)候顯示此屬性的標(biāo)題辣之,比如回退標(biāo)題太長了
headerRight: 定義導(dǎo)航欄右邊視圖
headerLeft: 定義導(dǎo)航欄左邊視圖
headerStyle: 定義導(dǎo)航欄的樣式,比如背景色等
headerTitleStyle: 定義標(biāo)題的樣式
headerBackTitleStyle: 定義返回標(biāo)題的樣式
headerTintColor: 定義導(dǎo)航條的tintColor减俏,會(huì)覆蓋headerTitleStyle中的顏色
gesturesEnabled: 定義是否能側(cè)滑返回召烂,iOS默認(rèn)true,Android默認(rèn)false
以上的 屬性使用很多知道是這個(gè),具體使用如下:
static navigationOptions=({
title:'首頁',
header:(
<View style={{width:Dimensions.get('window').width,height:64,backgroundColor:'red'}}/>
),
headerTitle:(
<View style={{width:60,height:20,backgroundColor:'red'}}/>
),
headerBackTitle:'哈哈哈哈哈',
headerTruncatedBackTitle:'你好',
headerRight:(
<View>
<Text>right</Text>
</View>
),
headerLeft:(
<View>
<Text>left</Text>
</View>
),
headerStyle: {
backgroundColor:'yellow'
},
headerTitleStyle:{
color:'red'
},
headerBackTitleStyle:{
tintColor:'#789'
},
headerTintColor:'#956',
gesturesEnabled:false
});
StackNavigatorConfig
主要是配置整個(gè)路由的娃承,包括跳轉(zhuǎn)動(dòng)畫奏夫,跳轉(zhuǎn)方式等。
initialRouteName: 初始化哪個(gè)界面為根界面历筝,如果不配置酗昼,默認(rèn)使用RouteConfigs中的第一個(gè)頁面當(dāng)做根界面
initialRouteParams: 初始化根界面參數(shù),主要是給根視圖傳遞一些參數(shù)梳猪,通過this.props.navigation.state.params可以取到
navigationOptions: 配置默認(rèn)的navigationOptions
paths: 官方意思是覆蓋已經(jīng)配置的路由麻削,可是我沒有試出來效果
mode: 跳轉(zhuǎn)方式,一種是card春弥,默認(rèn)的呛哟,在iOS上是從右到左跳轉(zhuǎn),在Android上是從下到上匿沛,都是使用原生系統(tǒng)的默認(rèn)跳轉(zhuǎn)方式扫责。一種是modal,只針對(duì)iOS平臺(tái)逃呼,模態(tài)跳轉(zhuǎn)鳖孤。
headerMode: 跳轉(zhuǎn)過程中,導(dǎo)航條的動(dòng)畫效果抡笼,有三個(gè)值苏揣,float表示會(huì)漸變,類似于iOS的原生效果推姻,screen表示沒有漸變平匈。none表示隱藏導(dǎo)航條
cardStyle: 可以統(tǒng)一定義界面的顏色,例如背景色
transitionConfig:配置頁面跳轉(zhuǎn)的動(dòng)畫
onTransitionStart: 頁面跳轉(zhuǎn)動(dòng)畫即將開始的回調(diào)
onTransitionEnd: 頁面跳轉(zhuǎn)動(dòng)畫結(jié)束的回調(diào)
具體代碼中的使用如下:
static stackNavigatorConfig = ({
initialRouteName:'First',
initialRouteParams:{
data:'haha'
},
navigationOptions:{
headerTintColor:'red'
},
mode:'card',
headerMode:'screen',
cardStyle:({backgroundColor:'blue'}),
onTransitionStart:((route)=>{
console.log('開始動(dòng)畫');
}),
onTransitionEnd:((route)=>{
console.log('結(jié)束動(dòng)畫');
}),
transitionConfig:(()=>({
//因?yàn)閕os 的導(dǎo)航動(dòng)畫默認(rèn)是從左到右,所以吐葱,這里配置一下動(dòng)畫街望,使用react-navigation已經(jīng)實(shí)現(xiàn)的從左到右的動(dòng)畫,
//適配Android弟跑,不過灾前,需要導(dǎo)入動(dòng)畫
//import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
screenInterpolator:CardStackStyleInterpolator.forHorizontal,
}))
});
頁面跳轉(zhuǎn)
配置完路由,看下他的屬性主要是下面這幾個(gè),然后使用在后面逐個(gè)講解:
navigate:路由方法孟辑,主要來啟動(dòng)另一個(gè)頁面
state:狀態(tài)哎甲,其實(shí)StackNavigator內(nèi)部維護(hù)了兩個(gè)路由棧,一個(gè)名為newState饲嗽,是當(dāng)前顯示頁面之前的所有頁面炭玫,包括當(dāng)前界面。一個(gè)名為lastState貌虾,當(dāng)然吞加,通過state還能拿到很多參數(shù)。
setParams: 設(shè)置參數(shù)尽狠,記住衔憨,一定不要在render方法中調(diào)用此方法。
goBack: 返回
dispatch: 給當(dāng)前界面設(shè)置action袄膏,會(huì)替換原來的跳轉(zhuǎn)践图,回退等事件
不是在路由配置JS文件中跳轉(zhuǎn)方式:
this.props.navigation.navigate('Second',{'data':'haha'});
參數(shù)的傳遞
實(shí)現(xiàn)導(dǎo)航器之間的傳遞參數(shù)就應(yīng)該在上一級(jí)頁面導(dǎo)航器中定義 一個(gè)參數(shù),然后在子頁面或者下級(jí)頁面接收完成傳遞沉馆。
如果要從前個(gè)頁面?zhèn)鬟f數(shù)據(jù):
1.更改上面跳轉(zhuǎn)步驟2中的點(diǎn)擊按鈕的方法如下码党,這種跳轉(zhuǎn)適合在路由配置頁面跳轉(zhuǎn):
onPress={() => navigate('Chat',{user : 'XiaoNiu'})}
2.在接受頁面的render 方法中定義如下,這個(gè)params 不能隨意取名字
const { params } = this.props.navigation.state;
3.使用直接{ params.user} 就可以了
4.如果要傳遞參數(shù)來設(shè)置下一界面的標(biāo)題可以按如下操作斥黑,但是要注意揖盘,在配置const SimpleApp = StackNavigator({。锌奴。兽狭。。缨叫。})里面對(duì)應(yīng)的頁面就不要設(shè)置headertitle 了椭符,那個(gè)地方的優(yōu)先級(jí)高荔燎,設(shè)置了傳過去沒效果耻姥。
a.傳參:
onPress={() =>navigate('Chat' ,{user:'我是受業(yè)的數(shù)據(jù)'})}
b.接受處理
使用一、在接受頁面的類中render 函數(shù)前執(zhí)行:
static navigationOptions = ({ navigation }) => ({
title: `Chat with ${navigation.state.params.user}`,
});
使用二有咨、在Render里渲染的時(shí)候琐簇,通過
1.先聲明常量
const { params } = this.props.navigation.state;
2.調(diào)用 params.user 使用(不能隨意取名字)
也可以使用這樣的方式跳轉(zhuǎn):
this.props.navigation.navigate('Detail')
goBack使用
回退到指定界面,如果什么都不傳,回退到上一個(gè)界面婉商,傳null似忧,回退到任意界面。傳key丈秩,可以回退到指定界面盯捌。例如:
this.props.navigation.goBack();
this.props.navigation.goBack(null);
this.props.navigation.goBack('Profile');
標(biāo)題的擴(kuò)展
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen,
navigationOptions:{
headerTitle:'詳情',
headerBackTitle:null,
} },
上面這個(gè) headerTitle 會(huì)覆蓋之前的設(shè)置的標(biāo)題,還有更多屬性擴(kuò)展如下:
navigationOptions:({navigation,screenProps}) => ({
// StackNavigator 屬性部分
// title:'Test1', 同步設(shè)置導(dǎo)航和tabbar文字,不推薦使用
headerTitle:'aaa', // 只會(huì)設(shè)置導(dǎo)航欄文字,
// header:{}, // 可以自定義導(dǎo)航條內(nèi)容蘑秽,如果需要隱藏可以設(shè)置為null
// headerBackTitle:null, // 設(shè)置跳轉(zhuǎn)頁面左側(cè)返回箭頭后面的文字饺著,默認(rèn)是上一個(gè)頁面的標(biāo)題〕ι可以自定義幼衰,也可以設(shè)置為null
// headerTruncatedBackTitle:'', // 設(shè)置當(dāng)上個(gè)頁面標(biāo)題不符合返回箭頭后的文字時(shí),默認(rèn)改成"返回"缀雳。
// headerRight:{}, // 設(shè)置導(dǎo)航條右側(cè)渡嚣。可以是按鈕或者其他肥印。
// headerLeft:{}, // 設(shè)置導(dǎo)航條左側(cè)识椰。可以是按鈕或者其他竖独。
headerStyle:{
backgroundColor:'#ff00FC',
elevation:0
}, // 設(shè)置導(dǎo)航條的樣式裤唠。如果想去掉安卓導(dǎo)航條底部陰影可以添加elevation: 0,iOS去掉陰影是。
headerTitleStyle:{
fontSize:30,
color:'white'
}, // 設(shè)置導(dǎo)航條文字樣式莹痢。安卓上如果要設(shè)置文字居中种蘸,只要添加alignSelf:'center'就可以了
// headerBackTitleStyle:{}, // 設(shè)置導(dǎo)航條返回文字樣式。
// headerTintColor:'green', // 設(shè)置導(dǎo)航欄文字顏色竞膳『讲t?偢杏X和上面重疊了。
gesturesEnabled:true, // 是否支持滑動(dòng)返回收拾坦辟,iOS默認(rèn)支持刊侯,安卓默認(rèn)關(guān)閉
// TabNavigator 屬性部分
// title:'', 同上
tabBarVisible:true, // 是否隱藏標(biāo)簽欄。默認(rèn)不隱藏(true)
tabBarIcon: (({tintColor,focused}) => {
return(
<Image
source={!focused ? ShiTuIcon : ShiTuIcon}
style={[{height:35,width:35 }, {tintColor: tintColor}]}
/>
)
}), // 設(shè)置標(biāo)簽欄的圖標(biāo)锉走。需要單獨(dú)設(shè)置滨彻。
tabBarLabel:'XX', // 設(shè)置標(biāo)簽欄的title。推薦這個(gè)方式挪蹭。
})
將需要跳轉(zhuǎn)的頁面注冊(cè)在這里 StackNavigator注冊(cè)下亭饵,全局才可以跳轉(zhuǎn)
導(dǎo)航配置
screen:對(duì)應(yīng)界面名稱,需要填入import之后的頁面梁厉。
navigationOptions:配置StackNavigator的一些屬性辜羊。
title:標(biāo)題,如果設(shè)置了這個(gè)導(dǎo)航欄和標(biāo)簽欄的title就會(huì)變成一樣的,所以不推薦使用這個(gè)方法八秃。
header:可以設(shè)置一些導(dǎo)航的屬性碱妆,當(dāng)然如果想隱藏頂部導(dǎo)航條只要將這個(gè)屬性設(shè)置為null就可以了笼裳。
headerTitle:設(shè)置導(dǎo)航欄標(biāo)題抵屿,推薦用這個(gè)方法。
headerBackTitle:設(shè)置跳轉(zhuǎn)頁面左側(cè)返回箭頭后面的文字惯殊,默認(rèn)是上一個(gè)頁面的標(biāo)題骤肛『嚼猓可以自定義,也可以設(shè)置為null
headerTruncatedBackTitle:設(shè)置當(dāng)上個(gè)頁面標(biāo)題不符合返回箭頭后的文字時(shí)萌衬,默認(rèn)改成"返回"饮醇。(上個(gè)頁面的標(biāo)題過長,導(dǎo)致顯示不下秕豫,所以改成了短一些的朴艰。)
headerRight:設(shè)置導(dǎo)航條右側(cè)』煲疲可以是按鈕或者其他祠墅。
headerLeft:設(shè)置導(dǎo)航條左側(cè)「杈叮可以是按鈕或者其他毁嗦。
headerStyle:設(shè)置導(dǎo)航條的樣式。背景色回铛,寬高等狗准。如果想去掉安卓導(dǎo)航條底部陰影可以添加elevation: 0,iOS下用shadowOpacity: 0茵肃。
headerTitleStyle:設(shè)置導(dǎo)航條文字樣式腔长。安卓上如果要設(shè)置文字居中,只要添加alignSelf:'center'就可以了验残。在安卓上會(huì)遇到捞附,如果左邊有返回箭頭導(dǎo)致文字還是沒有居中的問題,最簡單的解決思路就是在右邊也放置一個(gè)空的按鈕您没。
headerBackTitleStyle:設(shè)置導(dǎo)航條返回文字樣式鸟召。
headerTintColor:設(shè)置導(dǎo)航欄文字顏色“迸簦總感覺和上面重疊了欧募。
headerPressColorAndroid:安卓獨(dú)有的設(shè)置顏色紋理,需要安卓版本大于5.0
gesturesEnabled:是否支持滑動(dòng)返回收拾喻犁,iOS默認(rèn)支持槽片,安卓默認(rèn)關(guān)閉
gestureResponseDistance:對(duì)象覆蓋觸摸從屏幕邊緣開始的距離,以識(shí)別手勢肢础。 它需要以下屬性:
horizontal - number - 水平方向的距離 默認(rèn)為25还栓。
vertical - number - 垂直方向的距離 默認(rèn)為135。
// 設(shè)置滑動(dòng)返回的距離
gestureResponseDistance:{horizontal:300},
注:beta13新出的東西传轰,挺有意思剩盒,以后可以手動(dòng)控制返回了
導(dǎo)航視覺效果
mode:定義跳轉(zhuǎn)風(fēng)格。
card:使用iOS和安卓默認(rèn)的風(fēng)格慨蛙。
modal:iOS獨(dú)有的使屏幕從底部畫出辽聊。類似iOS的present效果
headerMode:邊緣滑動(dòng)返回上級(jí)頁面時(shí)動(dòng)畫效果。
float:iOS默認(rèn)的效果期贫,可以看到一個(gè)明顯的過渡動(dòng)畫跟匆。
screen:滑動(dòng)過程中,整個(gè)頁面都會(huì)返回通砍。
none:沒有動(dòng)畫玛臂。
cardStyle:自定義設(shè)置跳轉(zhuǎn)效果。
transitionConfig: 自定義設(shè)置滑動(dòng)返回的配置封孙。
onTransitionStart:當(dāng)轉(zhuǎn)換動(dòng)畫即將開始時(shí)被調(diào)用的功能迹冤。
onTransitionEnd:當(dāng)轉(zhuǎn)換動(dòng)畫完成,將被調(diào)用的功能虎忌。
path:路由中設(shè)置的路徑的覆蓋映射配置泡徙。
initialRouteName:設(shè)置默認(rèn)的頁面組件,必須是上面已注冊(cè)的頁面組件膜蠢。
initialRouteParams:初始路由的參數(shù)堪藐。
path:path屬性適用于其他app或?yàn)g覽器使用url打開本app并進(jìn)入指定頁面。path屬性用于聲明一個(gè)界面路徑挑围,例如:【/pages/Home】庶橱。此時(shí)我們可以在手機(jī)瀏覽器中輸入:app名稱://pages/Home來啟動(dòng)該App,并進(jìn)入Home界面贪惹。
屬性的使用方式
headerRight:(
<Text style={{color:'red',marginRight:20}} onPress={()=>navigation.state.params.navigatePress()}>我的</Text>
),
tabBarOptions: {
style: {
height:49
},
activeBackgroundColor:'white',
activeTintColor:'#4ECBFC',
inactiveBackgroundColor:'white',
inactiveTintColor:'#aaa',
showLabel:false,
注意里面的navigation.state.params.navigatePress()這句代碼苏章,這個(gè)可以調(diào)用另一個(gè)類的方法。比較神奇的W嗨病枫绅!
當(dāng)然,要注意上面的寫法有所改變:
navigationOptions:({navigation,screenProps})=>({})
頁面跳轉(zhuǎn) 傳遞參數(shù)與回傳
navigate('Detail',{
title:'圖片詳情',
url:item.url,
});
Detail:在StackNavigator中注冊(cè)的頁面硼端,需要一一對(duì)應(yīng)并淋,才能跳轉(zhuǎn)到相應(yīng)的頁面
title:在跳轉(zhuǎn)的頁面可以通過this.props.navigation.state.params.title獲取到這個(gè)參數(shù)。當(dāng)然這個(gè)參數(shù)可以隨便填寫珍昨,都可以通過this.props.navigation.state.params.xxx獲取县耽。
回調(diào)傳參
navigate('Detail',{
// 跳轉(zhuǎn)的時(shí)候攜帶一個(gè)參數(shù)去下個(gè)頁面
callback: (data)=>{
console.log(data); // 打印值為:'回調(diào)參數(shù)'
}
});
const {navigate,goBack,state} = this.props.navigation;
// 在第二個(gè)頁面,在goBack之前,將上個(gè)頁面的方法取到,并回傳參數(shù),這樣回傳的參數(shù)會(huì)重走render方法
state.params.callback('回調(diào)參數(shù)');
goBack();
具體看我下面的代碼:
<Button onPress={() => navigate('Chat', {
boom: this.state.boom,
callback: (data) => {
this.setState({
boom: data,
})
}
}
)}
title="Go Chat"
/>
接受頁面的代碼如下:
export class ChatScreen extends Component {
// static navigationOptions = {
// title: 'Chat',
// };
static navigationOptions = ({ navigation }) => ({
title: `${navigation.state.params.boom}`,
});
render() {
const { params } = this.props.navigation.state;
return (
<View>
<Text onPress={() => { navigate('HaHa', { where: '我來至遠(yuǎn)方' }) }}>Chat with Lucy{params.boom}{}</Text>
<Text onPress={() => this.haha()}>熱土體壇y{params.boom}{}</Text>
</View>
);
}
haha(){
const {navigate,goBack,state} = this.props.navigation;
// 在第二個(gè)頁面,在goBack之前,將上個(gè)頁面的方法取到,并回傳參數(shù),這樣回傳的參數(shù)會(huì)重走render方法
state.params.callback('nima ');
goBack();
}
}
使用的常見問題:
1.使用StackNavigator(RouteConfigs, StackNavigatorConfig)兩個(gè)屬性順序問題:
const SimpleApp = StackNavigator({
Home: {
screen: HomeScreen,
},
Detail: {
screen: DetailPage,
},
},{
stackNavigatorConfig: ({
screen:RecordPage,
initialRouteName: 'Record',
initialRouteParams: {
data: 'haha'
},
navigationOptions: {
headerTintColor: 'green'
},
});
如果把 這個(gè){stackNavigatorConfig}放在前面就要添加一個(gè)首屏的屬性 screen:RecordPage, 目前驗(yàn)證的initialRouteName: 'Record',屬性不好用句喷,
自定義標(biāo)題欄
兩種方案:
1.node_modules -- react-navigation -- src -- views -- Header.js 更改
2.另外一種方式就是,在navigationOptions中設(shè)置headerTitleStyle的alignSelf為 ' center '即可解決兔毙。
去除返回鍵文字顯示
【node_modules -- react-navigation -- src -- views -- HeaderBackButton.js】的91行代碼處唾琼,修改為如下即可。
動(dòng)態(tài)設(shè)置頭部按鈕事件:
當(dāng)我們?cè)陬^部設(shè)置左右按鈕時(shí)澎剥,肯定避免不了要設(shè)置按鈕的單擊事件锡溯,但是此時(shí)會(huì)有一個(gè)問題,navigationOptions是被修飾為static類型的哑姚,所以我們?cè)诎粹o的onPress的方法中不能直接通過this來調(diào)用Component中的方法祭饭。如何解決呢?在官方文檔中叙量,作者給出利用設(shè)置params的思想來動(dòng)態(tài)設(shè)置頭部標(biāo)題倡蝙。那么我們可以利用這種方式,將單擊回調(diào)函數(shù)以參數(shù)的方式傳遞到params绞佩,然后在navigationOption中利用navigation來取出設(shè)置到onPress即可:
解決快速點(diǎn)擊多次跳轉(zhuǎn)
當(dāng)我們快速點(diǎn)擊跳轉(zhuǎn)時(shí)悠咱,會(huì)開啟多個(gè)重復(fù)的界面,如何解決呢征炼。其實(shí)在官方git中也有提示析既,解決這個(gè)問題需要修改react-navigation源碼:
找到scr文件夾中的addNavigationHelpers.js文件,替換為如下文本即可:
export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) {
// 添加點(diǎn)擊判斷
let debounce = true;
return {
...navigation,
goBack: (key?: ?string): boolean =>
navigation.dispatch(
NavigationActions.back({
key: key === undefined ? navigation.state.key : key,
}),
),
navigate: (routeName: string,
params?: NavigationParams,
action?: NavigationAction,): boolean => {
if (debounce) {
debounce = false;
navigation.dispatch(
NavigationActions.navigate({
routeName,
params,
action,
}),
);
setTimeout(
() => {
debounce = true;
},
500,
);
return true;
}
return false;
},
/**
* For updating current route params. For example the nav bar title and
* buttons are based on the route params.
* This means `setParams` can be used to update nav bar for example.
*/
setParams: (params: NavigationParams): boolean =>
navigation.dispatch(
NavigationActions.setParams({
params,
key: navigation.state.key,
}),
),
};
}
底部導(dǎo)航
title - Tab標(biāo)題,可用作 headerTitle 和 tabBarLabel 回退標(biāo)題
tabBarVisible - Tab的是否可見谆奥,沒有設(shè)置的話默認(rèn)為 true
tabBarIcon - Tab的icon組件眼坏,可以根據(jù) {focused: boolean, tintColor: string} 方法來返回一個(gè)icon組件
tabBarLabel - Tab中顯示的標(biāo)題字符串或者組件,也可以根據(jù) { focused: boolean, tintColor: string } 方法返回一個(gè)組件
TabNavigatorConfig
tabBarComponent - Tab選項(xiàng)卡組件酸些,有 TabBarBottom 和 TabBarTop 兩個(gè)值宰译,在iOS中默認(rèn)為 TabBarBottom ,在Android中默認(rèn)為 TabBarTop 魄懂。
TabBarTop - 在頁面的頂部
TabBarBottom - 在頁面的底部
tabBarPosition - Tab選項(xiàng)卡的位置沿侈,有 top 或 bottom 兩個(gè)值
swipeEnabled - 是否可以滑動(dòng)切換Tab選項(xiàng)卡
animationEnabled - 點(diǎn)擊Tab選項(xiàng)卡切換界面是否需要?jiǎng)赢?lazy - 是否懶加載頁面
initialRouteName - 初始顯示的Tab對(duì)應(yīng)的頁面路由名稱
order - 用路由名稱數(shù)組來表示Tab選項(xiàng)卡的順序,默認(rèn)為路由配置順序
paths - 路徑配置
backBehavior - androd點(diǎn)擊返回鍵時(shí)的處理市栗,有 initialRoute 和 none 兩個(gè)值
initailRoute - 返回初始界面
none - 退出
tabBarOptions - Tab配置屬性缀拭,用在 TabBarTop 和 TabBarBottom 時(shí)有些屬性不一致:
用于 TabBarTop 時(shí):
activeTintColor - 選中的文字顏色
inactiveTintColor - 未選中的文字顏色
showIcon - 是否顯示圖標(biāo),默認(rèn)顯示
showLabel - 是否顯示標(biāo)簽填帽,默認(rèn)顯示
upperCaseLabel - 是否使用大寫字母蛛淋,默認(rèn)使用
pressColor - android 5.0以上的MD風(fēng)格波紋顏色
pressOpacity - android 5.0以下或者iOS按下的透明度
scrollEnabled - 是否可以滾動(dòng)
tabStyle - 單個(gè)Tab的樣式
indicatorStyle - 指示器的樣式
labelStyle - 標(biāo)簽的樣式
iconStyle - icon的樣式
style - 整個(gè)TabBar的樣式
用于 TabBarBottom 時(shí):
activeTintColor - 選中Tab的文字顏色
activeBackgroundColor - 選中Tab的背景顏色
inactiveTintColor - 未選中Tab的的文字顏色
inactiveBackgroundColor - 未選中Tab的背景顏色
showLabel - 是否顯示標(biāo)題,默認(rèn)顯示
style - 整個(gè)TabBar的樣式
labelStyle - 標(biāo)簽的樣式
tabStyle - 單個(gè)Tab的樣式
底部Tab導(dǎo)航示例
TabNavigator 篡腌,即是Tab選項(xiàng)卡褐荷,類似于原生 android 中的 TabLayout ,它的構(gòu)造函數(shù):
TabNavigator(RouteConfigs, TabNavigatorConfig)
api和 StackNavigator 類似嘹悼,參數(shù) RouteConfigs 是路由配置叛甫,參數(shù) TabNavigatorConfig是Tab選項(xiàng)卡配置层宫。
RouteConfigs
路由配置和 StackNavigator 中是一樣的,配置路由以及對(duì)應(yīng)的 screen 頁面其监, navigationOptions 為對(duì)應(yīng)路由頁面的配置選項(xiàng):
import React, {Component} from 'react';
import {StackNavigator, TabBarBottom, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
import TabBarItem from "./index18/TabBarItem";
export default class MainComponent extends Component {
render() {
return (
<Navigator/>
);
}
}
const TabRouteConfigs = {
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) => ({
tabBarLabel: '首頁',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
tintColor={tintColor}
focused={focused}
normalImage={require('./img/tabbar/pfb_tabbar_homepage_2x.png')}
selectedImage={require('./img/tabbar/pfb_tabbar_homepage_selected_2x.png')}
/>
),
}),
},
NearBy: {
screen: NearByScreen,
navigationOptions: {
tabBarLabel: '附近',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
tintColor={tintColor}
focused={focused}
normalImage={require('./img/tabbar/pfb_tabbar_merchant_2x.png')}
selectedImage={require('./img/tabbar/pfb_tabbar_merchant_selected_2x.png')}
/>
),
},
}
,
Mine: {
screen: MineScreen,
navigationOptions: {
tabBarLabel: '我的',
tabBarIcon: ({focused, tintColor}) => (
<TabBarItem
tintColor={tintColor}
focused={focused}
normalImage={require('./img/tabbar/pfb_tabbar_mine_2x.png')}
selectedImage={require('./img/tabbar/pfb_tabbar_mine_selected_2x.png')}
/>
),
},
}
};
const TabNavigatorConfigs = {
initialRouteName: 'Home',
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
lazy: true,
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
Tab: {
screen: Tab,
}
};
const StackNavigatorConfigs = {
initialRouteName: 'Tab',
navigationOptions: {
title: '標(biāo)題',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
頂部Tab選項(xiàng)卡示例
import React, {Component} from "react";
import {StackNavigator, TabBarTop, TabNavigator} from "react-navigation";
import HomeScreen from "./index18/HomeScreen";
import NearByScreen from "./index18/NearByScreen";
import MineScreen from "./index18/MineScreen";
export default class MainComponent extends Component {
render() {
return (
<Navigator/>
);
}
}
const TabRouteConfigs = {
Home: {
screen: HomeScreen,
navigationOptions: ({navigation}) => ({
tabBarLabel: '首頁',
}),
},
NearBy: {
screen: NearByScreen,
navigationOptions: {
tabBarLabel: '附近',
},
}
,
Mine: {
screen: MineScreen,
navigationOptions: {
tabBarLabel: '我的',
},
}
};
const TabNavigatorConfigs = {
initialRouteName: 'Home',
tabBarComponent: TabBarTop,
tabBarPosition: 'top',
lazy: true,
tabBarOptions: {}
};
const Tab = TabNavigator(TabRouteConfigs, TabNavigatorConfigs);
const StackRouteConfigs = {
Tab: {
screen: Tab,
}
};
const StackNavigatorConfigs = {
initialRouteName: 'Tab',
navigationOptions: {
title: '標(biāo)題',
headerStyle: {backgroundColor: '#5da8ff'},
headerTitleStyle: {color: '#333333'},
}
};
const Navigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);