Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs StackNavigator中的嵌套TabNavigator:控制标题_Reactjs_React Native_React Navigation - Fatal编程技术网

Reactjs StackNavigator中的嵌套TabNavigator:控制标题

Reactjs StackNavigator中的嵌套TabNavigator:控制标题,reactjs,react-native,react-navigation,Reactjs,React Native,React Navigation,我有一个类似这样的设置: let Tabs = createBottomTabNavigator({ screen1: Screen1, screen2: Screen2 }) let Stack = createStackNavigator({ tabs: Tabs otherScreen: OtherScreen }) 堆栈导航器有一个标题,这很好。我想要的是根据我当前所在的选项卡获得不同的标题图标 我正在使用以下版本: "react": "16.3.1"

我有一个类似这样的设置:

let Tabs = createBottomTabNavigator({
    screen1: Screen1,
    screen2: Screen2
})

let Stack = createStackNavigator({
    tabs: Tabs
    otherScreen: OtherScreen
})
堆栈导航器有一个标题,这很好。我想要的是根据我当前所在的选项卡获得不同的标题图标

我正在使用以下版本:

"react": "16.3.1",
"react-native": "~0.55.2",
"react-navigation": "^2.2.5"

我已经考虑过切换我的设置,这样每个选项卡屏幕都有自己的
StackNavigator
,但是我喜欢在切换选项卡时有滑动动画,我不希望标题图标滑动。标题栏应保持静态,但仅根据当前选项卡显示不同的图标。

您可以使用当前导航堆栈配置实现所需的行为。你可能需要改变一些东西,并结合一些属性,但当你开始考虑它时,这是相当简单的

我试着用一个小例子来解释它

考虑使用下面的导航器

const Tabs = createBottomTabNavigator({
    screen1: Tab1,
    screen2: Tab2
})

const Stack = createStackNavigator({
    tabs: {
      screen: TabsPage,
      navigationOptions: ({navigation}) => {
        return { title: (navigation.state.params && navigation.state.params.title ? navigation.state.params.title : 'No Title' ) }
      }
    },
    otherScreen: Page
})
如您所见,我正在从导航状态设置title参数。要想为导航器设置参数,我们需要从属性获取帮助

class TabsPage extends Component {
  onTabsChange = (title) => {
    this.props.navigation.setParams({ title })
  }
  render() {
    return(<Tabs screenProps={{ onTabsChange: this.onTabsChange }} />)
  }
}

当我们聚焦选项卡时,传递的函数将运行,然后为该选项卡设置标题。您可以使用此过程为标题设置不同的按钮或图标。您可以找到工作零食。

您可以像下面这样使用

//(navigation.state.routes[navigation.state.index])[“routeName”] //(navigation.state.routes[navigation.state.index][“routes”])[(navigation.state.routes[navigation.state.index][“index”])]

this will give the current route name of the tab inside StackNavigation.
上面的代码将TabBar所在的根堆栈头中的标题设置为第一个路由,因此我们将TabBar中单个堆栈的头设置为null。通过使用这种方式,将在切换选项卡栏中的屏幕时提供动画,因为标题将保持静态

你可以在这里找到工作副本

下载此文件并执行以下操作

  • npm安装//以获取依赖项

  • 响应本机升级//以获取android和ios文件夹

  • 对链接依赖项和库作出本机链接//反应

  • 反应本机运行ios(或)反应本机运行android

    你可以使用上面的,让我知道如果有的话


  • 在AppNavigation.js//中,或您已定义路线的位置

    let Tabs=createBottomTabNavigator({
    屏幕1:屏幕1,
    屏幕2:屏幕2
    })
    让Stack=createStackNavigator({
    标签:标签
    其他屏幕:其他屏幕
    },{
    headerMode:“float”//渲染一个停留在顶部的标题,并在屏幕更改时设置动画。这是iOS上的常见模式。
    headerTransitionPreset:“淡入位”//当标题图标更改时,这将提供轻微的过渡。
    }
    )
    const RootStack=createStackNavigator(
    {
    主屏幕:{屏幕:主屏幕},
    过滤器屏幕:CreateMaterialOptabNavigator({
    Tab1:{screen:Tab1Screen},
    Tab2:{screen:Tab2Screen},
    }),
    },
    {
    模式:“模态”,
    headerMode:“无”,
    }
    );
    render(){
    返回;
    }
    
    如果您使用的是react导航,您只需使用属性
    headershow:false
    。我创建了一个
    react导航
    版本的工作示例:
    5.x.x
    ,嵌套了不同的导航器:
    堆栈
    抽屉
    &
    底部选项卡

    以下是github的链接:

    有关更详细的概述,您可以查看我的博客:

    这确实是一个更好的解决方案,但如何导航到“其他屏幕”?this.props.navigation.navigate('Page');在Tab1或TAB2中不起作用,您可以检查此问题吗@bennygenel@AnthonyDe Smet,我已经更新了我的答案,请检查一下,让我知道这是否解决了您的问题。虽然这是可行的,但您不能将标题更改为routeName以外的任何内容,可以吗?e、 g.“Screen2”标题将始终为“Screen2”,或者您是否可以将其设置为:“子项XXX的屏幕标题”?@Chris,我已根据您的要求更新了我的答案。您可以通过在navigationOptions中使用与routeName匹配的switch case来设置标题headerLeft,headerRight等。通过这种方式,我们可以设置标题,而不必考虑routeName。@dhivyas我还有一个关于嵌套选项卡的问题,你认为我们可以用类似的解决方案来解决吗?你能检查这个Q@dhivyas你能检查这个Q@Ashwinmothillalcan你能检查这个Q@Rajatgupta你能检查这个Q@MahdiBashirpour吗
    //Screen1 Stack.
    
    const Screen1 = createStackNavigator ({
        Home: {
            screen: Home,
            navigationOptions: {
                header: null //Need to set header as null.
            }
        }
    });
    
    //Screen2 Stack
    
    const Screen2 = createStackNavigator ({
        Profile: {
            screen: Profile,
            navigationOptions: {
                header: null  //Need to set header as null.
            }
        }
    });
    
    
    let Tabs = createMaterialTopTabNavigator({
        Screen1:{
          screen: Screen1 //Calling Screen1 Stack.
        },
        Screen2:{
          screen: Screen2 //Calling Screen2 Stack.
        }
    },{ tabBarPosition: 'bottom' }) //this will set the TabBar at Bottom of your screen.
    
    let Stack = createStackNavigator({
        tabs:{
          screen: Tabs, //You can add the NavigationOption here with navigation as parameter using destructuring.
          navigationOptions: ({navigation})=>{
           //title: (navigation.state.routes[navigation.state.index])["routeName"]  
           //this will fetch the routeName of Tabs in TabNavigation. If you set the routename of the TabNavigation as your Header. 
    
           //use the following title property,this will fetch the current stack's routeName which will be set as your header in the TabBar.
    
            //title: (navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName
    
           //you can use switch case,on matching the route name you can set title of the header that you want and also header left and right icons similarly.
    
            switch ((navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName) {
                case "Screen1":
                    return {
                        title: "Home", 
                        headerLeft: (<Button
                            onPress={()=> alert("hi")}
                            title="Back"
                            color="#841584"
                            accessibilityLabel="Learn more about this purple button"
                        /> ),
                        headerRight: <Button title= "Right"/>
                    }
                case "Screen2":
                    return { 
                        title: "Profile",
                        headerLeft: (<Button
                            onPress={()=> alert("hi")}
                            title="Back"
                            color="#841584"
                            accessibilityLabel="Learn more about this purple button"
                        /> ),
                        headerRight: <Button title= "Right"/>
                    }
                default:
                    return { title: (navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName }
            }
          }
        },
        otherScreen:{
          screen: OtherScreen
        }
    })
    
      navigationOptions: ({navigation})=>{
       //title: (navigation.state.routes[navigation.state.index])["routeName"]  
       //this will fetch the routeName of Tabs in TabNavigation. If you set the routename of the TabNavigation as your Header. 
    
       //use the following title property,this will fetch the current stack's routeName which will be set as your header in the TabBar.
    
        //title: (navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName
    
        switch ((navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName) {
            case "Screen1":
                return {
                    title: "Home", 
                    headerLeft: (<Button
                        onPress={()=> alert("hi")} //Here you can able to set the back behaviour.
                        title="Back"
                        color="#841584"
                        accessibilityLabel="Learn more about this purple button"
                    /> ),
                    headerRight: <Button title= "Right"/>
                }
            case "Screen2":
                return { 
                    title: "Profile",
                    headerLeft: (<Button
                        onPress={()=> alert("hi")} 
                        title="Back"
                        color="#841584"
                        accessibilityLabel="Learn more about this purple button"
                    /> ),
                    headerRight: <Button title= "Right"/>
                }
            default:
                return { title: (navigation.state.routes[navigation.state.index]["routes"])[(navigation.state.routes[navigation.state.index]["index"])].routeName }
        }
      }    
    
    {
    
        "routes":[
            {
                "key":"Screen1",
                "routeName":"Screen1",
                "routes":[
                    {
                        "key":"Home",
                        "routeName":"Home",
                    }
                ],
                "index":0,
                "isTransitioning":false,
                "key":"id-1530276062643-0"
            },
            {
                "key":"Screen2",
                "routeName":"Screen2",
                "routes":[
                    {
                        "key":"Profile",
                        "routeName":"Profile",
                    }
                ],
                "index":0,
                "isTransitioning":false,
                "key":"id-1530276062643-0"
            }
        ],
        "index":0,
        "isTransitioning":false,
        "routeName":"tabs",
        "key":"id-1530276062643-0"
    
    }
    
    this will give the current route name of the tab inside StackNavigation.
    
    const RootStack = createStackNavigator(
      {
        Home: {screen: HomeScreen},
        FilterScreen: createMaterialTopTabNavigator({
            Tab1: {screen:Tab1Screen},
            Tab2: {screen: Tab2Screen},
        }),
      },
      {
        mode: 'modal',
        headerMode: 'none',
      }
    );
    
    
    render() {
        return <RootStack/>;
    }
    
    const Tabs = TabNavigator({
        Tab1:{
             screen: Tab1,
             navigationOptions: ({navigation}) => {
                return { title: "Tab 1 Heading", tabBarLabel:"Tab 1 "}
        },
        }
        Tab2:{
           screen: Tab2
           navigationOptions: ({navigation}) => {
             return { title: "Tab 2 Heading", tabBarLabel:"Tab 2 "}
        }
        }
    })
    
    const Stack = StackNavigator({
        tabs: {
          screen: Tabs
          navigationOptions: ({navigation}) => {
            return { title: "Stack"}
          }
        },
        otherScreen: Page
    })
    
    const Tabs = TabNavigator({
         Tab1:{
            screen: Tab1,
            navigationOptions: ({navigation}) => {
               return { tabBarLabel:"Tab 1 "}
            }},
         Tab2:{
            screen: Tab2
            navigationOptions: ({navigation}) => {
               return { tabBarLabel:"Tab 2 "}
            }}
    });
    Tabs.navigationOptions = ({navigation})=>{
        const { routeName } = navigation.state.routes[navigation.state.index]; //This gives current route
        switch(routeName){
             case "Tab1":
               headerTitle="Tab 1";
               break;
             case "Tab1":
               headerTitle="Tab 1";
               break;
        }
    
     return {
       headerTitle: headerTitle
    }
    }