Configuring Headers - 配置导航条

译注:下文中将Header统一翻译为导航条

导航条仅适用于StackNavigator

在前面的例子中,我们在应用里创建了一个StackNavigator来显示几个页面。

当跳转到Chat页面时,可以在navigate函数中为新route传入指定参数。因此,我们可以为Chat页面传递聊天对象的名字。

  1. this.props.navigation.navigate('Chat', { user: 'Lucy' });

这个user参数可以在Chat页面被获取:

  1. class ChatScreen extends React.Component {
  2. render() {
  3. const { params } = this.props.navigation.state;
  4. return <Text>Chat with {params.user}</Text>;
  5. }
  6. }

设置导航条标题

下一步,使用页面的参数来设置导航条的标题:

  1. class ChatScreen extends React.Component {
  2. static navigationOptions = ({ navigation }) => ({
  3. title: `Chat with ${navigation.state.params.user}`,
  4. });
  5. ...
  6. }


Configuring Headers - 配置导航条 - 图1 Configuring Headers - 配置导航条 - 图2


添加一个右侧按钮

接下来,我们添加一个navigationOptions对象,可以为header添加一个自定义的右侧按钮:

  1. static navigationOptions = {
  2. headerRight: <Button title="Info" />,
  3. ...


Configuring Headers - 配置导航条 - 图3 Configuring Headers - 配置导航条 - 图4


可以使用navigation prop来定义navigationOptions。让我们来根据route的参数渲染不同的按钮,并设置当按钮按下时调用navigation.setParams函数。

  1. static navigationOptions = ({ navigation }) => {
  2. const { state, setParams } = navigation;
  3. const isInfo = state.params.mode === 'info';
  4. const { user } = state.params;
  5. return {
  6. title: isInfo ? `${user}'s Contact Info` : `Chat with ${state.params.user}`,
  7. headerRight: (
  8. <Button
  9. title={isInfo ? 'Done' : `${user}'s info`}
  10. onPress={() => setParams({ mode: isInfo ? 'none' : 'info' })}
  11. />
  12. ),
  13. };
  14. };

现在,导航条可以与页面的route/state进行交互:


Configuring Headers - 配置导航条 - 图5 Configuring Headers - 配置导航条 - 图6


导航条与页面组件进行交互

有时候,导航条需要访问页面组件的属性,例如函数或状态。

比如说,我们想创建一个“编辑联系人信息”的页面,在导航条上有一个保存按钮,我们希望当保存信息时,用一个ActivityIndicator来代替保存按钮。

  1. class EditInfoScreen extends React.Component {
  2. static navigationOptions = ({ navigation }) => {
  3. const { params = {} } = navigation.state;
  4. let headerRight = (
  5. <Button
  6. title="Save"
  7. onPress={params.handleSave ? params.handleSave : () => null}
  8. />
  9. );
  10. if (params.isSaving) {
  11. headerRight = <ActivityIndicator />;
  12. }
  13. return { headerRight };
  14. };
  15. state = {
  16. nickname: 'Lucy jacuzzi'
  17. }
  18. _handleSave = () => {
  19. // Update state, show ActivityIndicator
  20. this.props.navigation.setParams({ isSaving: true });
  21. // Fictional function to save information in a store somewhere
  22. saveInfo().then(() => {
  23. this.props.navigation.setParams({ isSaving: false});
  24. })
  25. }
  26. componentDidMount() {
  27. // We can only set the function after the component has been initialized
  28. this.props.navigation.setParams({ handleSave: this._handleSave });
  29. }
  30. render() {
  31. return (
  32. <TextInput
  33. onChangeText={(nickname) => this.setState({ nickname })}
  34. placeholder={'Nickname'}
  35. value={this.state.nickname}
  36. />
  37. );
  38. }
  39. }

注:由于handleSave参数仅在组件安装时设置,因此不能立即在navigationOptions函数中使用。在设置handleSave之前,为了立即渲染并避免闪烁,我们给Button组件传递一个空的函数。