React Navigation 的使用基础部分(五)配置导航栏header bar

原文链接

此刻或许你已经厌倦了看见那个灰色的空白导航栏--想必你已经准备好了,让我们来配置导航栏吧!

设置导航栏

一个screen 组件有一个静态属性,叫做navigationOptions,可以是一个对象或者返回该对象的函数,这个对象包含不同的配置选项。我们用在导航栏标题的是title:

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
  };

  /* render function, etc */
}

class DetailsScreen extends React.Component {
  static navigationOptions = {
    title: 'Details',
  };

  /* render function, etc */
}

createStackNavigator 默认使用平台惯例,ios标题居中,安卓标题靠左。

在标题中使用参数

为了在标题中获取参数,我们需要让navigationOptions是一个返回配置对象的函数。在navigationOptions中使用this.props看上去没毛病,但是因为这是组件中的静态属性,所以this并不指向组件的实例,因此没有可用的属性。如果我们让navigationOptions成为一个函数,那么React Navigation调用的时候就会包含一个对象 { navigation, navigationOptions, screenProps }--这样,我们所关心的就只有navigation,而这与传递到screen中的属性this.props.navigation是一样的。你也许还记得我们可以使用navigation中的getParams来获得参数,所以我们这样做来提取并使用参数:

class DetailsScreen extends React.Component {
  static navigationOptions = ({ navigation }) => {
    return {
      title: navigation.getParam('otherParam', 'A Nested Details Screen'),
    };
  };

  /* render function, etc */
}

传递到navigationOptions中的参数是一个对象,包含以下属性:

  • navigation - screen的navigation prop , 在 navigation.state中是该screen的路由
  • screenProps - 从上级导航器组件中传递的属性
  • navigationOptions - 如果没有新值的话将会使用默认或者之前的选项值。

也许在某些情况下你需要用到screenProps和navigationOptions,但是以上例子中我们只用到navigation。


用setParams来更新 navigationOptions

我们经常需要在当前挂载的screen组件内部来更新navigationOptions。可以使用this.props.navigation.setParams。

 /* render()内部 */
  

调整导航栏样式

自定义导航栏样式有三个关键属性:headerStyle, headerTintColor, 和headerTitleStyle.

  • headerStyle: 包裹整个导航栏的View的样式对象。 backgroundColor 是导航栏的背景(elevation属性可以设置导航栏底部的阴影)
  • headerTintColor: 返回按钮和标题都是用这个属性作为作为颜色。在下边的例子中,tint color设置成白色,所以返回键和标题颜色都是白色。
  • headerTitleStyle: 如果我们向自定义标题的字体,字重或者其他字体样式,可以使用这个属性.
class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
    headerStyle: {
      backgroundColor: '#f4511e',
    },
    headerTintColor: '#fff',
    headerTitleStyle: {
      fontWeight: 'bold',
    },
  };

  /* render function, etc */
}

注意事项:

1 在ios中,状态栏文字和图标是黑色的,配一个深色背景颜色不太好看。这里不做过多讨论,不过你应该去配置状态栏来适应screen的颜色。

2 当前的配置只应用到home页面,当我们跳转到details页面时,默认样式是黑色。现在来看看如何配置通用的navigationOptions。


所有界面的共享 navigationOptions 

许多界面配置相似的导航栏的情况很普遍。例如,你们公司的品牌颜色是红色,所以你想要导航栏的背景色是红色,tint颜色(返回键和标题颜色)是白色。这就是我们示例中的颜色,当你跳转到详情页的时候会发现颜色变成默认的。如果我们把配置从主页中复制一份到详情页和app中的每一个界面,那简直是太糟糕了。谢天谢地我们并不需要这样。我们可以将配置移动位置。

class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Home',
    /* No more header config here! */
  };

  /* render function, etc */
}

/* other code... */

const RootStack = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailsScreen,
  },
  {
    initialRouteName: 'Home',
    /* The header config from HomeScreen is now here */
    navigationOptions: {
      headerStyle: {
        backgroundColor: '#f4511e',
      },
      headerTintColor: '#fff',
      headerTitleStyle: {
        fontWeight: 'bold',
      },
    },
  }
);

RootStack中的任何页面都会有相同的样式。然而,一定有方法来覆盖这些设置。


覆盖共享navigationOptions

在screen组件中指定的navigationOptions会和其父栈导航器中的配置合并。screen组件中的配置优先级高。让我们使用这些指示来改变详情页中的颜色。

class DetailsScreen extends React.Component {
  static navigationOptions = ({ navigation, navigationOptions }) => {
    const { params } = navigation.state;

    return {
      title: params ? params.otherParam : 'A Nested Details Screen',
      /* These values are used instead of the shared configuration! */
      headerStyle: {
        backgroundColor: navigationOptions.headerTintColor,
      },
      headerTintColor: navigationOptions.headerStyle.backgroundColor,
    };
  };

  /* render function, etc */
}

自定义组件替换标题

有时候我们不仅仅只是想修改title的文字和样式,而是想更好的控制导航栏--比如想在title的位置渲染一张图片,或者让title是一个按钮。在这种情况下你可以完全覆盖用作title的组件并且提供一个自定义的。

class LogoTitle extends React.Component {
  render() {
    return (
      
    );
  }
}

class HomeScreen extends React.Component {
  static navigationOptions = {
    // headerTitle instead of title
    headerTitle: ,
  };

  /* render function, etc */
}

You might be wondering, why headerTitle when we provide a component and not title, like before?(不知道怎么翻译好)。原因是headerTitle是一个针对栈导航器(还有别的导航器 比如tab导航器)的属性,headerTitle默认是一个Text组件,用来显示title属性中设置的内容。


其他配置

栈导航器完整的navigationOptions配置


总结

  • 你可以在screen组件的静态属性navigationOptions中自定义导航栏。
  • 静态属性navigationOptions可以是对象或者函数。当他是一个函数时,提供一个对象,该对象包含navigation prop, screenProps, 和navigationOptions属性
  • 你也可以在初始化栈导航器的时候指定一个公共的navigationOptions 。screen中的静态属性优先于该配置。

你可能感兴趣的:(React Navigation 的使用基础部分(五)配置导航栏header bar)