How to add header bar when using createBottomTabNavigator?












0














I'm trying to add a constant Header bar to my screen (all screens, similar to this example) with basic functionality (menu button, and a back button), but I'm having trouble finding a way to do this when using createBottomTabNavigator. I haven't seen anything saying this isn't possible, so if I'm making a design mistake, do let me know.



Here is my minimal foobar example (it runs):



import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';


class ScreenA extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen A'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};

class ScreenB extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen B'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};


const BottomTabNav = createBottomTabNavigator(
{
ScreenA: {
screen: ScreenA,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-card' : 'ios-card-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
}
},
ScreenB: {
screen: ScreenB,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-chatbubbles' : 'ios-chatbubbles-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
},
}
},
{
initialRouteName: 'ScreenA',
}
);


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


const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});


Apologies for not including a Snack link, but I'm having issues with dependencies when trying to build the demo.










share|improve this question


















  • 1




    you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
    – vonovak
    Nov 25 '18 at 1:59
















0














I'm trying to add a constant Header bar to my screen (all screens, similar to this example) with basic functionality (menu button, and a back button), but I'm having trouble finding a way to do this when using createBottomTabNavigator. I haven't seen anything saying this isn't possible, so if I'm making a design mistake, do let me know.



Here is my minimal foobar example (it runs):



import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';


class ScreenA extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen A'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};

class ScreenB extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen B'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};


const BottomTabNav = createBottomTabNavigator(
{
ScreenA: {
screen: ScreenA,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-card' : 'ios-card-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
}
},
ScreenB: {
screen: ScreenB,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-chatbubbles' : 'ios-chatbubbles-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
},
}
},
{
initialRouteName: 'ScreenA',
}
);


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


const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});


Apologies for not including a Snack link, but I'm having issues with dependencies when trying to build the demo.










share|improve this question


















  • 1




    you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
    – vonovak
    Nov 25 '18 at 1:59














0












0








0







I'm trying to add a constant Header bar to my screen (all screens, similar to this example) with basic functionality (menu button, and a back button), but I'm having trouble finding a way to do this when using createBottomTabNavigator. I haven't seen anything saying this isn't possible, so if I'm making a design mistake, do let me know.



Here is my minimal foobar example (it runs):



import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';


class ScreenA extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen A'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};

class ScreenB extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen B'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};


const BottomTabNav = createBottomTabNavigator(
{
ScreenA: {
screen: ScreenA,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-card' : 'ios-card-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
}
},
ScreenB: {
screen: ScreenB,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-chatbubbles' : 'ios-chatbubbles-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
},
}
},
{
initialRouteName: 'ScreenA',
}
);


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


const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});


Apologies for not including a Snack link, but I'm having issues with dependencies when trying to build the demo.










share|improve this question













I'm trying to add a constant Header bar to my screen (all screens, similar to this example) with basic functionality (menu button, and a back button), but I'm having trouble finding a way to do this when using createBottomTabNavigator. I haven't seen anything saying this isn't possible, so if I'm making a design mistake, do let me know.



Here is my minimal foobar example (it runs):



import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';


class ScreenA extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen A'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};

class ScreenB extends React.Component {
constructor(props) {
super(props);
this.state = {
screenName: 'Screen B'
}
}

render() {
return (
<View
style={styles.container}
>
<Text>{this.state.screenName}</Text>
</View>
);
}
};


const BottomTabNav = createBottomTabNavigator(
{
ScreenA: {
screen: ScreenA,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-card' : 'ios-card-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
}
},
ScreenB: {
screen: ScreenB,
navigationOptions: {
title: '',
tabBarIcon: ({ focused, tintColor }) => {
return <Ionicons
name={ focused ? 'ios-chatbubbles' : 'ios-chatbubbles-outline' }
size={30}
style={{ marginTop: 6 }}
/>;
},
},
}
},
{
initialRouteName: 'ScreenA',
}
);


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


const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});


Apologies for not including a Snack link, but I'm having issues with dependencies when trying to build the demo.







react-native






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 23 '18 at 21:24









ralston3ralston3

508415




508415








  • 1




    you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
    – vonovak
    Nov 25 '18 at 1:59














  • 1




    you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
    – vonovak
    Nov 25 '18 at 1:59








1




1




you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
– vonovak
Nov 25 '18 at 1:59




you probably want all your screens in the tab navigator (ScreenA, ScreenB) to be Stack navigators, eg. you'd say const ScreenA = createStackNavigator(...)
– vonovak
Nov 25 '18 at 1:59












1 Answer
1






active

oldest

votes


















0














Unfortunately, the default createBottomTabNavigator has no props for specifying header for each tab screen because making separate tab screen header is not an ideal use-case. Instead ideally all the tabs share a common header so in react native that can be done by wrapping the tab navigator inside a stack.



If you need different headers for each of your tabs, then consider making a generic header component that suits you app needs and attach it on the render inside your main container as first child and keep another child with flex:1 . Please have a look to the code below



//Header.js

import React from 'react';
import ReactNative, { StyleSheet } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';

import * as CONST from '../../util/constants';

export default ({title, hasBackButton, goBack}) => {
return (
<ReactNative.View style={styles.headerContainer}>
{hasBackButton && <ReactNative.TouchableOpacity onPress={goBack} style={styles.goBackButton}>
<Icon name='arrow-back' size={28} color={CONST.WHITE_COLOR} />
</ReactNative.TouchableOpacity>}
<ReactNative.View style={styles.textView}>
<ReactNative.Text style={styles.titleText}>{title}</ReactNative.Text>
</ReactNative.View>
{hasBackButton && <ReactNative.View style={styles.goBackButton}/>}
</ReactNative.View>
);
};

const styles = StyleSheet.create({
headerContainer: {
flexDirection: 'row',
height: 54,
backgroundColor: CONST.SECONDARY_COLOR,
paddingHorizontal: 16
},
goBackButton: {
paddingLeft: 0,
paddingRight: 5,
width: 40,
paddingVertical: 5,
justifyContent: 'center',
},
textView: {
flex:1,
paddingVertical: 5,
justifyContent: 'center',
},
titleText: {
fontSize: 22,
color: CONST.WHITE_COLOR,
fontWeight: '400',
},
});


In the component (Tab Screen component), you can use it like below:



render() {
return (
<ReactNative.View style={styles.container}>
<Header title='Tab1' />
<ReactNative.View style={{flex:1}}>
.... your design goes here..
</ReactNative.View>
</ReactNative.View>
);
}


Hope this helps.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453083%2fhow-to-add-header-bar-when-using-createbottomtabnavigator%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Unfortunately, the default createBottomTabNavigator has no props for specifying header for each tab screen because making separate tab screen header is not an ideal use-case. Instead ideally all the tabs share a common header so in react native that can be done by wrapping the tab navigator inside a stack.



    If you need different headers for each of your tabs, then consider making a generic header component that suits you app needs and attach it on the render inside your main container as first child and keep another child with flex:1 . Please have a look to the code below



    //Header.js

    import React from 'react';
    import ReactNative, { StyleSheet } from 'react-native';
    import Icon from 'react-native-vector-icons/MaterialIcons';

    import * as CONST from '../../util/constants';

    export default ({title, hasBackButton, goBack}) => {
    return (
    <ReactNative.View style={styles.headerContainer}>
    {hasBackButton && <ReactNative.TouchableOpacity onPress={goBack} style={styles.goBackButton}>
    <Icon name='arrow-back' size={28} color={CONST.WHITE_COLOR} />
    </ReactNative.TouchableOpacity>}
    <ReactNative.View style={styles.textView}>
    <ReactNative.Text style={styles.titleText}>{title}</ReactNative.Text>
    </ReactNative.View>
    {hasBackButton && <ReactNative.View style={styles.goBackButton}/>}
    </ReactNative.View>
    );
    };

    const styles = StyleSheet.create({
    headerContainer: {
    flexDirection: 'row',
    height: 54,
    backgroundColor: CONST.SECONDARY_COLOR,
    paddingHorizontal: 16
    },
    goBackButton: {
    paddingLeft: 0,
    paddingRight: 5,
    width: 40,
    paddingVertical: 5,
    justifyContent: 'center',
    },
    textView: {
    flex:1,
    paddingVertical: 5,
    justifyContent: 'center',
    },
    titleText: {
    fontSize: 22,
    color: CONST.WHITE_COLOR,
    fontWeight: '400',
    },
    });


    In the component (Tab Screen component), you can use it like below:



    render() {
    return (
    <ReactNative.View style={styles.container}>
    <Header title='Tab1' />
    <ReactNative.View style={{flex:1}}>
    .... your design goes here..
    </ReactNative.View>
    </ReactNative.View>
    );
    }


    Hope this helps.






    share|improve this answer




























      0














      Unfortunately, the default createBottomTabNavigator has no props for specifying header for each tab screen because making separate tab screen header is not an ideal use-case. Instead ideally all the tabs share a common header so in react native that can be done by wrapping the tab navigator inside a stack.



      If you need different headers for each of your tabs, then consider making a generic header component that suits you app needs and attach it on the render inside your main container as first child and keep another child with flex:1 . Please have a look to the code below



      //Header.js

      import React from 'react';
      import ReactNative, { StyleSheet } from 'react-native';
      import Icon from 'react-native-vector-icons/MaterialIcons';

      import * as CONST from '../../util/constants';

      export default ({title, hasBackButton, goBack}) => {
      return (
      <ReactNative.View style={styles.headerContainer}>
      {hasBackButton && <ReactNative.TouchableOpacity onPress={goBack} style={styles.goBackButton}>
      <Icon name='arrow-back' size={28} color={CONST.WHITE_COLOR} />
      </ReactNative.TouchableOpacity>}
      <ReactNative.View style={styles.textView}>
      <ReactNative.Text style={styles.titleText}>{title}</ReactNative.Text>
      </ReactNative.View>
      {hasBackButton && <ReactNative.View style={styles.goBackButton}/>}
      </ReactNative.View>
      );
      };

      const styles = StyleSheet.create({
      headerContainer: {
      flexDirection: 'row',
      height: 54,
      backgroundColor: CONST.SECONDARY_COLOR,
      paddingHorizontal: 16
      },
      goBackButton: {
      paddingLeft: 0,
      paddingRight: 5,
      width: 40,
      paddingVertical: 5,
      justifyContent: 'center',
      },
      textView: {
      flex:1,
      paddingVertical: 5,
      justifyContent: 'center',
      },
      titleText: {
      fontSize: 22,
      color: CONST.WHITE_COLOR,
      fontWeight: '400',
      },
      });


      In the component (Tab Screen component), you can use it like below:



      render() {
      return (
      <ReactNative.View style={styles.container}>
      <Header title='Tab1' />
      <ReactNative.View style={{flex:1}}>
      .... your design goes here..
      </ReactNative.View>
      </ReactNative.View>
      );
      }


      Hope this helps.






      share|improve this answer


























        0












        0








        0






        Unfortunately, the default createBottomTabNavigator has no props for specifying header for each tab screen because making separate tab screen header is not an ideal use-case. Instead ideally all the tabs share a common header so in react native that can be done by wrapping the tab navigator inside a stack.



        If you need different headers for each of your tabs, then consider making a generic header component that suits you app needs and attach it on the render inside your main container as first child and keep another child with flex:1 . Please have a look to the code below



        //Header.js

        import React from 'react';
        import ReactNative, { StyleSheet } from 'react-native';
        import Icon from 'react-native-vector-icons/MaterialIcons';

        import * as CONST from '../../util/constants';

        export default ({title, hasBackButton, goBack}) => {
        return (
        <ReactNative.View style={styles.headerContainer}>
        {hasBackButton && <ReactNative.TouchableOpacity onPress={goBack} style={styles.goBackButton}>
        <Icon name='arrow-back' size={28} color={CONST.WHITE_COLOR} />
        </ReactNative.TouchableOpacity>}
        <ReactNative.View style={styles.textView}>
        <ReactNative.Text style={styles.titleText}>{title}</ReactNative.Text>
        </ReactNative.View>
        {hasBackButton && <ReactNative.View style={styles.goBackButton}/>}
        </ReactNative.View>
        );
        };

        const styles = StyleSheet.create({
        headerContainer: {
        flexDirection: 'row',
        height: 54,
        backgroundColor: CONST.SECONDARY_COLOR,
        paddingHorizontal: 16
        },
        goBackButton: {
        paddingLeft: 0,
        paddingRight: 5,
        width: 40,
        paddingVertical: 5,
        justifyContent: 'center',
        },
        textView: {
        flex:1,
        paddingVertical: 5,
        justifyContent: 'center',
        },
        titleText: {
        fontSize: 22,
        color: CONST.WHITE_COLOR,
        fontWeight: '400',
        },
        });


        In the component (Tab Screen component), you can use it like below:



        render() {
        return (
        <ReactNative.View style={styles.container}>
        <Header title='Tab1' />
        <ReactNative.View style={{flex:1}}>
        .... your design goes here..
        </ReactNative.View>
        </ReactNative.View>
        );
        }


        Hope this helps.






        share|improve this answer














        Unfortunately, the default createBottomTabNavigator has no props for specifying header for each tab screen because making separate tab screen header is not an ideal use-case. Instead ideally all the tabs share a common header so in react native that can be done by wrapping the tab navigator inside a stack.



        If you need different headers for each of your tabs, then consider making a generic header component that suits you app needs and attach it on the render inside your main container as first child and keep another child with flex:1 . Please have a look to the code below



        //Header.js

        import React from 'react';
        import ReactNative, { StyleSheet } from 'react-native';
        import Icon from 'react-native-vector-icons/MaterialIcons';

        import * as CONST from '../../util/constants';

        export default ({title, hasBackButton, goBack}) => {
        return (
        <ReactNative.View style={styles.headerContainer}>
        {hasBackButton && <ReactNative.TouchableOpacity onPress={goBack} style={styles.goBackButton}>
        <Icon name='arrow-back' size={28} color={CONST.WHITE_COLOR} />
        </ReactNative.TouchableOpacity>}
        <ReactNative.View style={styles.textView}>
        <ReactNative.Text style={styles.titleText}>{title}</ReactNative.Text>
        </ReactNative.View>
        {hasBackButton && <ReactNative.View style={styles.goBackButton}/>}
        </ReactNative.View>
        );
        };

        const styles = StyleSheet.create({
        headerContainer: {
        flexDirection: 'row',
        height: 54,
        backgroundColor: CONST.SECONDARY_COLOR,
        paddingHorizontal: 16
        },
        goBackButton: {
        paddingLeft: 0,
        paddingRight: 5,
        width: 40,
        paddingVertical: 5,
        justifyContent: 'center',
        },
        textView: {
        flex:1,
        paddingVertical: 5,
        justifyContent: 'center',
        },
        titleText: {
        fontSize: 22,
        color: CONST.WHITE_COLOR,
        fontWeight: '400',
        },
        });


        In the component (Tab Screen component), you can use it like below:



        render() {
        return (
        <ReactNative.View style={styles.container}>
        <Header title='Tab1' />
        <ReactNative.View style={{flex:1}}>
        .... your design goes here..
        </ReactNative.View>
        </ReactNative.View>
        );
        }


        Hope this helps.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 24 '18 at 17:54

























        answered Nov 24 '18 at 17:46









        Suraj MalviyaSuraj Malviya

        818414




        818414






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53453083%2fhow-to-add-header-bar-when-using-createbottomtabnavigator%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

            Calculate evaluation metrics using cross_val_predict sklearn

            Insert data from modal to MySQL (multiple modal on website)