如何在(嵌套的)StackNavigator中实现自定义标题图标?

时间:2018-11-21 12:42:16

标签: react-native

这可能是一个讨厌的问题,但是尽管我阅读了文档和其他资源,但仍然没有弄清如何在StackNavigator的标题中实现两个或更多其他可单击图标,就像在图片中一样。如果stackNavigator要显示一个后图标,则允许他覆盖菜单图标。

这是(根)主屏幕的外观。用户开始单击内容后,应使用stackNavigator中的后退按钮替换菜单项(最好在任何平台上)。 Mockup of what I want to achieve.

到目前为止,我所做的事情:我从全新的模板开始,在运行tabs时选择了选项expo init。我在文件 MainTabNavigator.js

中做了一些小的修改
import React from 'react';
import { Platform } from 'react-native';
import { createStackNavigator, createBottomTabNavigator } from 'react-navigation';
import CustomHeader from '../components/CustomHeader';
import HomeScreen from '../screens/HomeScreen';    

const HomeStack = createStackNavigator( { Home: HomeScreen }, {
   // default config for screens in the stack, so `Home` will use this title 
  navigationOptions: { 
    title: 'Protype Prompter: Browse',
    header: props => <CustomHeader {...props} />,
    }}
);
// All other code stays like provided by expo init.
export default createBottomTabNavigator({
  HomeStack,
});

接下来,我确保在 HomeScreen.js 中,标题不会被覆盖:

export default class HomeScreen extends React.Component {
  /* static navigationOptions = {
    header: null,
  }; */

请帮助我使用 CustomHeader.js 。到目前为止,我的所有努力并未导致主屏幕上出现任何可见的变化。

import React from "react";
import { Header } from "react-navigation";
import { View, Platform, Image, StyleSheet } from "react-native";
import { SimpleLineIcons } from '@expo/vector-icons'; 
const CustomHeader = props => {
  return (
    <View>
        <SimpleLineIcons name="menu" size={24} color={tintColor} />
         <Header headerLeft={<SimpleLineIcons name="menu" size={24} color='#6a1b9a' />} {...props} />
    </View>
  );
};
export default CustomHeader;

除其他资源外,我到目前为止还访问了以下网站:

  1. headersheader buttons上的文档
  2. 一个github discussion on a react-navitation issue
  3. 一个howto on modifying headers和另一个customer headers with react-navigation。后者似乎是一个很好的起点。

3 个答案:

答案 0 :(得分:2)

实际上,这很容易。考虑到您正在使用React Navigation V2或V3,请看一下createStackNavigator docs

您有一个headerLeft和一个headerRight设置,可以同时使用一个自定义组件。因此,您可以轻松编写示例标头。

编辑

因此,我快速编写了一个示例:

在您的App.js中:

import React, { Component } from "react";
import Navigator from "./navigation/navigation";

export default class App extends Component {
  render() {
    return <Navigator />;
  }
}

navigation.js

import { createStackNavigator } from "react-navigation";
import HomeScreen from "../screens/HomeScreen";

const RootStack = createStackNavigator({ HomeScreen });

export default RootStack;

现在,您可以按屏幕在屏幕上设计标题,如下所示:

import React, { Component } from "react";
import { Platform, StyleSheet, Text, View } from "react-native";
import { SafeAreaView } from "react-navigation";
import { Icon } from "react-native-elements";

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  icon: {
    paddingLeft: 10
  },
  iconContainer: {
    flexDirection: "row",
    justifyContent: "space-evenly",
    width: 120
  }
});

export class HomeScreen extends Component {
  static navigationOptions = {
    title: "Title",
    headerLeft: (
      <Icon
        containerStyle={styles.icon}
        type="ionicon"
        name={Platform.OS === "ios" ? "ios-menu" : "md-menu"}
      />
    ),
    headerRight: (
      <View style={styles.iconContainer}>
        <Icon type="ionicon" name={Platform.OS === "ios" ? "ios-search" : "md-search"} />
        <Icon type="ionicon" name={Platform.OS === "ios" ? "ios-heart" : "md-heart"} />
        <Icon type="ionicon" name={Platform.OS === "ios" ? "ios-more" : "md-more"} />
      </View>
    )
  };

  render() {
    return (
      <SafeAreaView styles={styles.container}>
        <Text>Hi from the HomeScreen.</Text>
      </SafeAreaView>
    );
  }
}

export default HomeScreen;

我从react-native-elements中使用了the <Icon /> component。您可以通过为其提供onPress属性来使这些图标可点击。

这是iOS上结果的屏幕截图:

enter image description here

无耻的插头: 如果您想了解更多关于React Navigation you might like my tutorial的知识,我将在其中指导您构建具有生产就绪导航设置的应用程序。

答案 1 :(得分:1)

您可以在类中使用类似下面提到的代码的东西。

static navigationOptions = {
    headerTitle: 'Home Page',
    headerRight: (
      <View style={{ flexDirection: 'row' }}>
        <TouchableOpacity activeOpacity={0.7}
            onPress={() => { params.logoutClick() }}>
            <Text style={navItemTxt}> Logout</Text>
        </TouchableOpacity >
        <TouchableOpacity activeOpacity={0.7}
            onPress={() => { params.clearCartClick() }}>
            <Image source={require('../images/search/ic_clear_cart.png')}
                style={navItemImg} />
        </TouchableOpacity >
        <ConnectedBadgeTitle navigation={navigation} badgeAction={() => { navigation.navigate('Cart'); }} />
    </View >
    ),
  };

答案 2 :(得分:0)

让我们考虑一下route.js是否如下

import {
StackNavigator,
} from 'react-navigation';
import Home from './home.js';
import Login from './login.js';

export default Navigator = StackNavigator({
Home: { screen: Home },
Login: { screen: Login },
});

使用native-base可以创建自定义标题视图

CustomHeader.js

import { Header,Left, Right, Body, Thumbnail } from 'native-base';
<Header style={{ backgroundColor: '#f8f8f8', alignItems: 'center', justifyContent: 'center' }}>
             <Left style={{ flexDirection: 'row' }}>
                  <Icon name='ios-menu-outline' color='#000' size={26} style={{ paddingLeft: 15, width: 40 }} onPress={} />
              </Left>
             <Body style={{}}>
                <Text style={{}}>Name</Text>
            </Body>
           <Right>
              <Icon name='ios-menu-outline' color='#000' size={26} style={{ paddingLeft: 15, width: 40 }} onPress={} />
           </Right>
        </Header>

home.js文件,如下所示

对于抽屉Drawer component

static navigationOptions = {
    header: null,
};

在抽屉组件下可以创建自定义标题

render(){
  return(
    <Drawer > //Assumed you have some drawer component
        <CustomHeader data={"title"}/>
        <ScrollView>
        </ScrollView>
    </Drawer>
  )
}