之前copy别人的代码,看 Navigator 使用起来还是很简单的,可是当自己亲自去coding的时候,感觉完全不是一回事,这篇博客记录自己遇到的坑!
问题一:使用 navigator.push 点击跳转后,手指滑动可以返回上一页,但是打log发现并没有调用 pop 方法,而且还是可以滑动回去,根本原因暂不追究,上代码:
<span style="font-size:18px;">_addNavigator(component, title){
var data = null;
if(title === '首页'){
data = this.state.data;
}
return <Navigator
style={{flex:1}}
initialRoute={{
component: component,
title: title,
passProps:{
data: data
}
}}
</span><pre name="code" class="javascript"><span style="font-size:18px;">configureScene={(route) => {
return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
}}</span>
renderScene={(route, navigator) => { let Component = route.component; return <Component {...route.params} navigator={navigator} /> }}/>; } 这个是主要的路由,后来发现关键在于:
<span style="font-size:18px;">configureScene={(route) => {
return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
}}</span>
详细配置请看源代码的: node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
HorizontalSwipeJumpFromRight: {
...BaseConfig,
gestures: {
jumpBack: {
...BaseRightToLeftGesture,
overswipe: BaseOverswipeConfig,
edgeHitWidth: null,
isDetachable: true,
},
jumpForward: {
...BaseLeftToRightGesture,
overswipe: BaseOverswipeConfig,
edgeHitWidth: null,
isDetachable: true,
},
pop: BaseRightToLeftGesture,
},
animationInterpolators: {
into: buildStyleInterpolator(FromTheLeft),
out: buildStyleInterpolator(FadeToTheRight),
},
},
关键就在 gestures:{} 里面,我们可以在源码里找到:
FadeAndroid: {
...BaseConfig,
gestures: null,
animationInterpolators: {
into: buildStyleInterpolator(FadeIn),
out: buildStyleInterpolator(FadeOut),
},
},
就不难发现,只要把gestures设置成null,就不能触摸返回了!
问题二:Navigator传递参数问题:
MainPage.js中:
_addNavigator(component, title){
var data = null;
if(title === JOURNEY_TAB){
data = this.state.data;
}
return <Navigator
style={{flex:1}}
initialRoute={{
component: component,
title: title,
passProps:{
data: data
}
}}
// configureScene={(route) => {
// return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
// }}
renderScene={(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}}/>;
}
Journey.js中,list列表选中后,跳转到详细页面:
selectJourney(journey: Object) {
const {navigator} = this.props;
if(navigator){
navigator.push({
name: 'JourneyDetail',
component: JourneyDetail,
params: {
journeyData: journey,
}
});
}
}
JourneyDetail.js中,点击返回按钮:
_pressBackButton(){
const { navigator } = this.props;
if(navigator) {
navigator.pop();
}
}
需求:我现在有TabNavigator, TabNavigator上有Journey、SecondPage、...几个页面,需要在从 Journey跳转到JourneyDetail的时候TabNavigator隐藏,然后从JourneyDetail跳转回来Journey的时候,TabNavigator显示,隐藏和显示的方法已经写好,只需要一个boolean参数就可以了,
因为看到在MainPage.js中:
renderScene={(route, navigator) => {
let Component = route.component;
return <Component {...route.params} navigator={navigator} />
}
然后后面的几个页面全部都可以通过
const { navigator } = this.props;
获取到navigator,而且MainPage.js中的Component就是对应的TabNavigator上的几个页面,所以在想,是不是在
<Component {...route.params} navigator={navigator} />
上定义的属性都是可以在之后的几个页面的js上获取到呢?事实证明猜想是对的,于是我把MainPage.js修改为:
_addNavigator(component, title){
var data = null;
if(title === JOURNEY_TAB){
data = this.state.data;
}
return <Navigator
style={{flex:1}}
initialRoute={{
component: component,
title: title,
passProps:{
data: data
}
}}
// configureScene={(route) => {
// return Navigator.SceneConfigs.HorizontalSwipeJumpFromRight;
// }}
renderScene={(route, navigator) => {
let Component = route.component;
return <Component {...route.params} show={(is_show) => {
this.setState({showTabBar: is_show});
}} navigator={navigator} />
}}/>;
}
增加了一个show={(is_show) => {xxx}}来改变显示和隐藏的状态,
Journey.js中,在跳转到详细页面时候,改变状态:
selectJourney(journey: Object) {
const {navigator,show} = this.props;
show(false);
console.log(show);
if(navigator){
navigator.push({
name: 'JourneyDetail',
component: JourneyDetail,
params: {
journeyData: journey,
show: function(is_show){
show(is_show);
}
}
});
}
}
并接收从详情页面返回来的参数 is_show;
JourneyDetail.js中:
_pressBackButton(){
const { navigator } = this.props;
if(this.props.show){
this.props.show(true);
}
if(navigator) {
navigator.pop();
}
}
点击返回按钮的时候,调用pop()前,
this.props.show(true);