因項目升級到0.47.1,之前的navigator不能再使用,so再次研究了react-navigation的使用,先推薦下寫的不錯的文章~
- ReactNative導(dǎo)航新寵兒react-navigation
- React Native——react-navigation的使用
- React Native未來導(dǎo)航者:react-navigation 使用詳解
- react-navigation使用
- React-navigation之StackNavigator
- redux與react-navigation的集成
- React Navigation官方文檔
(一)StackNavigator參數(shù)詳解
const AppNavigator = StackNavigator(StackRouteConfigs, StackNavigatorConfigs);
下面來詳細介紹下兩個參數(shù):
RouteConfigs
它主要是來配置頁面路由的,所有的界面都必須配置在里面。
示例:
const StackRouteConfigs = {
Splash: {
screen: Splash, // 界面
navigationOptions: {
header: null // 無標題欄
}
},
Login: {
screen: Login,
navigationOptions: {
header: null
}
},
Main: {
screen: TabBarNavigator,
navigationOptions: {
header: null
}
},
Registered: {
screen: Registered,
navigationOptions: {
header: null
}
},
LoginSms: {
screen: LoginSms,
navigationOptions: {
header: null
}
}
};
上面用到了一個參數(shù)navigationOptions,他是用來配置頁面的標題參數(shù)。我們可以在路由里面配置參數(shù),像上面的示例一樣;你也可以在頁面中配置,需要在頁面中定義一個靜態(tài)常量navigationOptions。
navigationOptions
參數(shù)說明:
title: 這個即可以作為頭部標題,也可以作為返回標題和Tab標題
header: 自定義導(dǎo)航條,系統(tǒng)的導(dǎo)航條會隱藏
headerTitle: 標題
headerBackTitle: 回退標題
headerTruncatedBackTitle: 當回退標題不能顯示的時候顯示此屬性的標題,比如回退標題太長了
headerRight: 定義導(dǎo)航欄右邊視圖
headerLeft: 定義導(dǎo)航欄左邊視圖
headerStyle: 定義導(dǎo)航欄的樣式,比如背景色等
headerTitleStyle: 定義標題的樣式
headerBackTitleStyle: 定義返回標題的樣式
headerTintColor: 定義導(dǎo)航條的tintColor,會覆蓋headerTitleStyle中的顏色
gesturesEnabled: 定義是否能側(cè)滑返回,iOS默認true,Android默認false
具體頁面中配置示例:
static navigationOptions=({
title:'首頁',
header:(
<View style={{width:Dimensions.get('window').width,height:64,backgroundColor:'#1B82D1'}}/>
),
headerTitle:(
<View style={{width:60,height:20,backgroundColor:'#F0F'}}/>
),
headerBackTitle:'返回',
headerTruncatedBackTitle:'回退',
headerRight:(
<View>
<Text>right</Text>
</View>
),
headerLeft:(
<View>
<Text>left</Text>
</View>
),
headerStyle: {
backgroundColor:'yellow'
},
headerTitleStyle:{
color:'red'
},
headerBackTitleStyle:{
tintColor:'#E8E8E8'
},
headerTintColor:'#F33',
gesturesEnabled:false
});
StackNavigatorConfig
這個參數(shù)主要是配置整個路由的,包括跳轉(zhuǎn)動畫,跳轉(zhuǎn)方式等。
參數(shù)說明:
initialRouteName: 初始化哪個界面為根界面,如果不配置,默認使用RouteConfigs中的第一個頁面當做根界面
initialRouteParams: 初始化根界面參數(shù),主要是給根視圖傳遞一些參數(shù),通過this.props.navigation.state.params可以取到
navigationOptions: 配置默認的navigationOptions
paths: 官方意思是覆蓋已經(jīng)配置的路由,但我沒試
mode: 跳轉(zhuǎn)方式,一種是card,默認的,在iOS上是從右到左跳轉(zhuǎn),在Android上是從下到上,都是使用原生系統(tǒng)的默認跳轉(zhuǎn)方式。一種是modal,只針對iOS平臺,模態(tài)跳轉(zhuǎn)。
headerMode: 跳轉(zhuǎn)過程中,導(dǎo)航條的動畫效果,有三個值,float表示會漸變,類似于iOS的原生效果,screen表示沒有漸變。none表示隱藏導(dǎo)航條
cardStyle: 可以統(tǒng)一定義界面的顏色,例如背景色
transitionConfig:配置頁面跳轉(zhuǎn)的動畫,是一個方法
onTransitionStart: 頁面跳轉(zhuǎn)動畫即將開始的回調(diào)方法
onTransitionEnd: 頁面跳轉(zhuǎn)動畫結(jié)束的回調(diào)方法
示例:
const StackNavigatorConfigs = {
initialRouteName: 'Splash', // 初始化哪個界面為根界面
initialRouteParams:{
data:'你好Navigation'
},
navigationOptions:{
headerTintColor:'blue'
},
mode:'card', // 跳轉(zhuǎn)方式:默認的card,在iOS上是從右到左跳轉(zhuǎn),在Android上是從下到上,都是使用原生系統(tǒng)的默認跳轉(zhuǎn)方式。
headerMode:'screen', // 導(dǎo)航條動畫效果:float表示會漸變,類似于iOS的原生效果,screen表示沒有漸變。none表示隱藏導(dǎo)航條
cardStyle:({
backgroundColor:'#FFF'
}),
onTransitionStart:((route)=>{
console.log('開始動畫');
}),
onTransitionEnd:((route)=>{
console.log('結(jié)束動畫');
}),
transitionConfig:(()=>({
//因為ios 的導(dǎo)航動畫默認是從左到右,所以,這里配置一下動畫,使用react-navigation已經(jīng)實現(xiàn)的從左到右的動畫,
//適配Android,不過,需要導(dǎo)入動畫
//import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
screenInterpolator:CardStackStyleInterpolator.forHorizontal,
}))
};
注:
CardStackStyleInterpolator.forHorizontal // 從左到右
CardStackStyleInterpolator.forVertical // 從下到上
CardStackStyleInterpolator.forFadeFromBottomAndroid // 從底部淡出
(二)Navigation Prop
屬性說明:
navigate:路由方法,主要來啟動另一個頁面
state:狀態(tài),通過state能拿到很多參數(shù)。
setParams: 設(shè)置參數(shù),記住,一定不要在render方法中調(diào)用此方法。
goBack: 返回
dispatch: 給當前界面設(shè)置action,會替換原來的跳轉(zhuǎn),回退等事件
如圖所示,是打印的Navigation屬性:
navigate
此方法可以傳三個參數(shù):navigate(routeName, params, action)
routeName: 頁面名稱,一定要在路由配置中配置。
params: 傳遞參數(shù)到下一個頁面
action: action
- 跳轉(zhuǎn)界面示例:
this.props.navigation.navigate('Registered');
- 傳參跳轉(zhuǎn)示例:
this.props.navigation.navigate('LoginSms', {
loginPhone: this.state.phoneNumber
});
另一界面接收該值:
constructor(props) {
super(props);
const loginPhone = this.props.navigation.state.params.loginPhone;
}
state
通過state,我們能拿到傳遞過來的參數(shù),如上方獲取loginPhone示例。
goBack
如果什么都不傳,回退到上一個界面;傳null,回退到任意界面;傳key,可以回退到指定界面。
示例:
this.props.navigation.goBack(); // 回退到上一個界面
this.props.navigation.goBack(null); // 回退到任意界面
this.props.navigation.goBack('Login'); // 回退到指定界面
setParams
設(shè)置當前頁面的參數(shù),記住,調(diào)用此方法一定要在componentDidMount
示例:
componentDidMount() {
var {setParams} = this.props.navigation;
setParams({'loginPhone':'13800001111'});
}
dispatch
所有的Navigation Actions都會返回一個對象,這個對象可以使用navigation.dispatch方法傳遞到router。
下面的actions是可以使用的:
- Navigate-導(dǎo)航到其他的route
- Reset-使用新的state代替目前的state
- Back-返回上一個state
- Set Params-給定的route設(shè)置參數(shù)
- Init-如果state沒有定義,用來初始化第一個state
action詳解
1.Navigate
Navigatie action會使用Navigate action的結(jié)果來更新當前的state。
- routeName,字符串,必選項,在app的router里注冊的導(dǎo)航目的地的routeName。
- params,對象,可選項,融合進目的地route的參數(shù)。
- actions,對象,可選項(高級),如果screen也是一個navigator,次級action可以在子router中運行。在文檔中描述的任何actions都可以作為次級action。
import { NavigationActions } from 'react-navigation';
const navigateAction = NavigationActions.navigate({
routeName: 'Splash',
params: {},
action: NavigationActions.navigate({ routeName: 'Login'})
});
this.props.navigation.dispatch(navigateAction);
2.Reset
Reset action刪掉所有的navigation state并且使用幾個actions的結(jié)果來代替。
- index,數(shù)組,必選,navigation state中route數(shù)組中激活route的index。
- actions,數(shù)組,必選項,Navigation Actions數(shù)組,將會替代navigation state。
import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: 'Main'})
]
});
this.props.navigation.dispatch(resetAction);
index參數(shù)的使用
index參數(shù)被用來定制化當前激活的route。舉個栗子:使用兩個routes Login和Main給一個基礎(chǔ)的stack navigation設(shè)置。為了重置route到Main,但是在堆棧中又存放在Login screen之上,你可以這么做:
import { NavigationActions } from 'react-navigation'
const resetAction = NavigationActions.reset({
index: 1,
actions: [
NavigationActions.navigate({ routeName: 'Login'}),
NavigationActions.navigate({ routeName: 'Main'})
]
});
this.props.navigation.dispatch(resetAction);
3.Back
返回到前一個screen并且關(guān)閉當前screen.backaction creator接受一個可選的參數(shù):
- key:字符串或者空,可選項,如果設(shè)定了,navigation將會從設(shè)定的key返回;如果是null,navigation將返回到任何地方。
import { NavigationActions } from 'react-navigation'
const backAction = NavigationActions.back({
key: 'Home'
});
this.props.navigation.dispatch(backAction);
4.SetParams
當dispatching setParams的時候,router將會產(chǎn)出一個新的state,這個state是已經(jīng)改變了特定route的參數(shù),以key作為身份驗證。
- params:對象,必選參數(shù),融合進已經(jīng)存在的route參數(shù)中的新參數(shù)。
- key:字符串,必選參數(shù),Route的key,應(yīng)該分配給新的參數(shù)。
import { NavigationActions } from 'react-navigation'
const setParamsAction = NavigationActions.setParams({
params: { title: '首頁' },
key: 'id-1503398147429-3',
});
this.props.navigation.dispatch(setParamsAction);
(三)自定義NavigationBar
通過對上面的StackNavigator的了解,我們可以使用自定義的NavigationBar,也就是標題欄。
具體自定義NavigationBar的代碼就不貼了,我們來說說怎樣讓自定義的標題欄和StackNavigator建立聯(lián)系,從而可以使用goBack和navigate等方法進行界面回退、跳轉(zhuǎn)等操作。
我們在自定義NavigationBar的時候,在render方法中會定義一個屬性navigator,而我們在其他界面使用自定義的NavigationBar的時候會將這個屬性傳到NavigationBar中,這樣我們就可以在自定義NavigationBar中使用goBack(),navigate等方法了。例如:
loginSms.js
...
render() {
const navigator = this.props.navigation;
const {phoneNumber, smsCode} = this.state;
return (
<View
style={stylesCommon.container}
>
<NavigationBar
title={'登錄'}
navigator={navigator}
/>
...
</View>
);
}
...
navigationBar.js
render() {
const {
navigator,
title,
backIconClick,
leftButtonConfig,
style,
...
} = this.props;
let leftButtonConfig = this.props.leftButtonConfig;
if (!leftButtonConfig) {
leftButtonConfig = {
type: 'image',
image: backIcon,
onClick: () => {
if (backIconClick) {
backIconClick();
} else {
if (navigator && !leftButtonHidden) {
console.log('--------navigator-------',navigator);
navigator.goBack();
}
}
},
};
}
return(
...
);
}
注:通過打印'--------navigator-------'發(fā)現(xiàn),navigator傳值時一定要傳
const navigator = this.props.navigation;
而不能傳const {navigate} = this.props.navigation;
后者只是傳了navigation屬性中的navigate方法,而非整個navigation,我們獲取不到goBack()方法,導(dǎo)致報錯。