每个页面都可以配置来决定它在导航器中的呈现方式。在基础文档的配置标题栏部分,我们介绍了它的工作原理。
在本文档中,我们将会解释当有多个导航器一起使用时它是如何工作的。看完该章节,你将学习到如何将navigationOptions放在正确的位置,并确保可以正确的配置导航器。如果你把它们放在错误的地方,有可能什么都不会发生,但也可能会发生令人困惑和意外的事情。值得庆幸的是,以下的环节理解起来相对比较简单。
只能从导航器的某个屏幕组件来修改它的导航选项。这同样适用于导航器嵌套使用的情况
试想这样的一种情形:一个选项卡导航器,导航器的每个tab又包含了一个堆栈导航器。假如我们在堆栈导航器的某个屏幕配置navigationOptions,会产生什么效果?
1 | class A extends React.Component { |
正如我们上边提到的:只能从导航器的某个屏幕组件来修改它的导航选项。上边代码中的A和B是分别属于HomeStack和SettingStack的屏幕组件,而不是属于选项卡导航器的屏幕组件。因此,当我们在A和B配置tabBarLabel属性时,在选项卡导航器上是没有任何效果的。我们将代码稍作修改,来达到我们想要的效果:
1 | import React from 'react'; |
为了弄清上边的逻辑,我们先回想以下的代码:MyComponent和MyOtherComponent两个组件的效果是一样的
1 | class MyComponent extends React.Component { |
另外,我们也了解到,createStackNavigator函数和相关的一些函数是可以返回一个react组件的。因此,当HomeStack和SettingStack作为某个导航器的屏幕组件时,我们直接在HomeStack和SettingStack配置navigationOptions时,相当于我们控制了它父类导航器的navigationOptions。
堆栈导航器嵌套一个选项卡导航器,并希望设置堆栈导航器的title
1 | const TabNavigator = createBottomTabNavigator({ |
以上边的代码为例,假如我们在FeedScreen页面中,通过navigationOptions配置headerTitle属性,将不会达到我们想要的效果。因为AppNavigator堆栈导航器只会查找它的直接子屏幕(TabNavigator和SettingScreen)的配置。因此,为了设置AppNavigator的title,我们可以通过TabNavigator来它的headerTitle。如下方的代码:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15const TabNavigator = createBottomTabNavigator({
Feed: FeedScreen,
Profile: ProfileScreen,
});
TabNavigator.navigationOptions = ({ navigation }) => {
let { routeName } = navigation.state.routes[navigation.state.index];
// You can do whatever you like here to pick the title based on the route name
let headerTitle = routeName;
return {
headerTitle,
};
};
还有另外一种情形:每个tab页面有自己的堆栈导航器,你可以选择当某个tab被选中时,隐藏顶层堆栈导航器的标题部分
1 | const FeedStack = createStackNavigator({ |
选项卡导航器包含一个堆栈导航器,你希望在特殊的页面隐藏选项卡工具条
1 | const FeedStack = createStackNavigator({ |
以上边的代码为例,假如希望当从feed页面跳转到detials页面时,将选项卡工具条隐藏。我们不能通过在DetailsScreen的navigationOptions中设置tabBarVisible:false这种写法来达到效果,因为这些配置只会作用于FeedStack。为了达到这个效果,我们需要按照以下这种写法:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66import React from 'react';
import { View, Text, TouchableHighlight } from 'react-native';
import {
createStackNavigator,
createBottomTabNavigator,
} from 'react-navigation';
const Placeholder = ({ text }) => (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>{text}</Text>
</View>
);
class FeedScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TouchableHighlight onPress={() => this.props.navigation.navigate('Details')}>
<Text>go to Details</Text>
</TouchableHighlight>
</View>
);
}
}
FeedScreen.navigationOptions = {
title: "FeedScreen",
};
class DetailsScreen extends React.Component {
render() {
return <Placeholder text="DetailsScreen!" />;
}
}
DetailsScreen.navigationOptions = {
title: "DetailsScreen",
};
class ProfileScreen extends React.Component {
render() {
return <Placeholder text="ProfileScreen!" />;
}
}
const FeedStack = createStackNavigator({
FeedHome: FeedScreen,
Details: DetailsScreen,
});
export default createBottomTabNavigator({
Feed: FeedStack,
Profile: ProfileScreen,
});
FeedStack.navigationOptions = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
};
};
抽屉里面有一个堆栈导航器,你希望在某些特定屏幕上锁定抽屉功能
这与上一小节比较类似,上一小节是在特定的屏幕隐藏选项卡工具条,而这一小节是在特定的屏幕锁定抽屉功能,使用的是drawerLockMode属性而不是tabBarVisible属性
1 | const FeedStack = createStackNavigator({ |
为了实当我们跳转到Details页面时将抽屉隐藏的效果。我们需要在FeedStack中配置navigationOptions,因为假如我们在DetailsScreen中配置navigationOptions ,它将直接作用于它的父类导航器FeedStack,而不是抽屉导航器
1 | import React from 'react'; |