# 配置标题栏

我们已经看到了如何配置标题,但让我们再来一遍,然后继续其他选项-重复是学习的关键!

# 设置标题

Screen 组件接受 options 属性,它可以是一个对象,也可以是一个返回对象的函数,该对象包含各种配置选项。我们在标头标题中使用的是 title ,如下面的示例所示。

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ title: "My home" }}
      />
    </Stack.Navigator>
  );
}

# 在标题中使用参数

为了在标题中使用参数,我们需要为屏幕的 options 设置一个返回配置对象的函数。 在 options 属性中使用 this.props 可能很诱人,但是因为它是在组件呈现之前定义的,所以 this 不能引用组件的实例,因此没有属性可用。相反,如果我们将 options 作为一个函数,那么 React Navigation 将使用一个包含 { navigation, route } 的对象来调用它 —— 在本例中,我们只关心 route,这是与传递到您的屏幕 props 中的 route 是同一个对象。你可能还记得,我们可以通过路由得到参数。下面我们这样做是为了提取一个参数并将它用作一个标题。

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ title: "My home" }}
      />
      <Stack.Screen
        name="Profile"
        component={ProfileScreen}
        options={({ route }) => ({ title: route.params.name })}
      />
    </Stack.Navigator>
  );
}

传递给 options 函数的参数是一个具有以下属性的对象:

  • navigation — 屏幕上的 navigation prop
  • route - 屏幕的 route prop

在上面的例子中,我们只需要 route,但是在某些情况下,你可能也想使用 navigation

# 使用 setOptions 更新 options

通常需要从挂载的屏幕组件本身更新活动屏幕的 options 配置。我们可以使用 navigation.setOptions 来实现这一点

/* Inside of render() of React class */
<Button
  title="Update the title"
  onPress={() => navigation.setOptions({ title: "Updated!" })}
/>

# 调整页眉样式

有三个关键属性用于自定义你的标题的样式: headerStyle, headerTintColorheaderTitleStyle

  • headerStyle: 一个样式对象,将被应用到包装头部的 View 中。如果你设置了 backgroundColor,它就会成为你 header 的颜色。
  • headerTintColor: 后退按钮和标题都使用这个属性作为它们的颜色。在下面的例子中,我们将颜色设置为白色(#fff),这样后退按钮和标题将是白色的。
  • headerTitleStyle: 如果我们想定制标题的 fontFamily, fontWeight 和其他 Text 样式属性,我们可以使用这个来做。
function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{
          title: "My home",
          headerStyle: {
            backgroundColor: "#f4511e",
          },
          headerTintColor: "#fff",
          headerTitleStyle: {
            fontWeight: "bold",
          },
        }}
      />
    </Stack.Navigator>
  );
}

这里有几件事需要注意:

  1. 在 iOS 上,状态栏的文本和图标都是黑色的,这在深色背景下看起来不太好。我们不会在这里讨论它,但是您应该确保配置状态栏以适应您的屏幕颜色,如 状态栏指南 (opens new window) 中所述。
  2. 我们设置的配置只适用于主屏幕;当我们导航到细节屏幕时,默认的样式又回来了。现在我们来看一下如何在屏幕之间共享选项。

# 跨屏幕共享公共选项

通常希望以类似的方式在多个屏幕上配置标题。例如,您的公司品牌颜色可能是红色的,因此您希望标题背景色为红色,色调为白色。这些就是我们正在运行的示例中使用的颜色,您会注意到,当您导航到DetailsScreen时,颜色返回到默认值。如果我们必须将 options 标题样式属性从 HomeScreen 复制到 DetailsScreen,并为我们在应用中使用的每个屏幕组件复制选项,这不是很糟糕吗?谢天谢地,我们没有。我们可以将配置移到堆栈导航器的 screenOptions 属性下面。

function StackScreen() {
  return (
    <Stack.Navigator
      screenOptions={{
        headerStyle: {
          backgroundColor: "#f4511e",
        },
        headerTintColor: "#fff",
        headerTitleStyle: {
          fontWeight: "bold",
        },
      }}
    >
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ title: "My home" }}
      />
    </Stack.Navigator>
  );
}

现在,任何屏幕属于 StackScreen 将有我们美妙的品牌风格。当然,如果我们需要的话,一定有办法推翻这些选项吧?

# 用自定义组件替换标题

有时您需要更多的控制,而不仅仅是更改标题的文本和样式——例如,您可能想要渲染一个图像来代替标题,或将标题变成一个按钮。在这些情况下,您可以完全覆盖用于标题的组件,并提供您自己的组件。

function LogoTitle() {
  return (
    <Image
      style={{ width: 50, height: 50 }}
      source={require("@expo/snack-static/react-native-logo.png")}
    />
  );
}

function StackScreen() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ headerTitle: (props) => <LogoTitle {...props} /> }}
      />
    </Stack.Navigator>
  );
}

您可能想知道,当我们提供组件而不是像以前那样提供 title 时,为什么要提供 headerTitle 呢? 原因是,headerTitle 是一个特定于堆栈导航器的属性,headerTitle 默认为一个显示标题的 Text 组件。

# 额外的配置

您可以在 createStackNavigator (opens new window) 引用中阅读堆栈导航器中屏幕的可用 options 的完整列表。

# 总结

  • 您可以自定义屏幕组件的 options 属性内部的标题。请阅读 API 参考 (opens new window) 中的完整选项列表。
  • options 可以是对象或函数。当它是一个函数时,它会提供一个带有 navigationroute 属性的对象。
  • 初始化堆栈导航器时,还可以在堆栈导航器配置中指定共享 screenOptions。这个属性优先于配置。