Arun kumar
Arun kumar

Reputation: 1081

How to get drawer over the header in react navigation?

I am using react navigation. I want to show drawer over the header of the screen. Currently my header is not hiding below drawer when I open the drawer.

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { createStackNavigator, createDrawerNavigator  } from 'react-navigation';
import CategoryScreen from './CategoryScreen';
import ProductsScreen from './ProductsScreen';
import CartScreen from './CartScreen';


const drawerScreens = createDrawerNavigator ({
    Category: CategoryScreen,
    Products: ProductsScreen,
},{
    initialRouteName: 'Category'
}
)


export default AppStack = createStackNavigator(
    { 
        drawer: {
            screen: drawerScreens,
            navigationOptions: ({ navigation }) => ({
                header: <View style={styles.container}><Text>Header</Text></View>
              }),
        }, 
        cart: {screen: CartScreen} 
    },
    {
        initialRouteName: 'drawer',
    }
);

const styles = StyleSheet.create({
    container: {
        height: 100,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: 'orange',
    }
})

So how to show the header which is overlaped or covered with drawer of drawer navigation.

Currently its look like this

enter image description here

Upvotes: 13

Views: 17224

Answers (3)

Mazhar k
Mazhar k

Reputation: 251

Hope this will help you in this ...

           export function DrawerContent(props) {

               return(

                <View style={{flex:1}}>
               <DrawerContentScrollView {...props}>
               <View style={styles.drawerContent}>
               <View style={styles.userInfoSection}>
               <View style={{flexDirection:'row',marginTop: 15}}>
               <Avatar.Image size={50} />
               <View style={{marginLeft:15, flexDirection:'column'}}>
               <Title style={styles.title}>{status}</Title>
               <Caption style={styles.caption}>@_something</Caption>

                        </View>
                    </View>
                </View>
            </View>

        </DrawerContentScrollView>
      
    </View>
);
  }
         const styles = StyleSheet.create({
            userInfoSection: {
             paddingLeft: 20,
                         },
                          title: {
                fontSize: 16,
                marginTop: 3,
                  fontWeight: 'bold',
                   },
                   caption: {
                   fontSize: 14,
                   lineHeight: 14,
                     },

                 
                 });

In App.js in Drawer navigation container I passed DrawerContent as a props and import DrawerContent component in app.js main as shown

  const Navigation (){
      return(
  <Drawer.Navigator initialRouteName="Home"  drawerContent={props =><DrawerContent {...props} />}>
  <Drawer.Screen name="Home" component={HomeScreen} options={{marginLeft:5}} />
  <Drawer.Screen name="Notifications" component={NotificationsScreen} />
  </Drawer.Navigator>
  )
  }
     export default const App = ()=> {
                    return (
                           <NavigationContainer>
                              <Navigation />
                            </NavigationContainer>
               );
                   };

Upvotes: 0

Ali SabziNezhad
Ali SabziNezhad

Reputation: 3118

In my case, i make my own Header component and use it in each page i want. it enabled me to customize header with each page.

Absolutely it is the back door way and i hope other people have the exact answer of your question.

This is an example...

Home page:

export default class Home extends Component {
    render() {  
        return (
            <View style={{ flex: 1 }}>

                <Header showBorder={true}/>

                <ScrollView>
                   ...
                </ScrollView>
            </View>
        );
    }
}

Header Component:

export default class Header extends React.PureComponent {

  renderTitle = () => {
    if (this.props.title) {
      return (
        <View style={{ flexDirection: 'column', flex: 3, justifyContent: 'center' }}>
          <View style={{ alignSelf: 'flex-start' }}>
            <Text style={[styles.fontBold, { fontSize:17, color: colors.borderWidthColor }]}>{this.props.title}</Text>
          </View>
        </View>
      )
    }
  }

  renderBack = () => {
    if (this.props.back) {
      return (
        <View style={{ marginTop:3 }}>
          <TouchableOpacity
            onPress={() => {
              this.props.navigation.goBack()
            }}
            style={{ alignSelf: 'flex-start' }}>
            <Icon name="md-arrow-back" size={23} color="black" />
          </TouchableOpacity>
        </View>
      )
    }
  }


  render() {
    return (
      <View style={[{ height: 70, backgroundColor: this.props.backgroundColor, width: win.width, borderBottomWidth: this.props.showBorder ? 1 : 0 }]}>
        <View style={{ flex: 1, flexDirection: 'row', marginTop: Platform.OS == 'ios' ? 17 : 3 }}>
          <View style={{ flexDirection: 'column', flex: 1, justifyContent: 'center', marginLeft: 12 }}>
            {this.renderBack()}
            {this.renderTitle()}
          </View>
        </View>
      </View>
    )
  }
}

Upvotes: 2

usergio2
usergio2

Reputation: 469

  1. You should create a new StackNavigator for your CategoryScreen and ProductScreen
  2. You set the header on CategoryScreen and ProductScreen navigation options

Here is what i meant

// wrap your screen inside the drawer into StackNavigator
const CategoryNavigator = createStackNavigator({
  CategoryList: {
    screen: CategoryScreen,
    navigationOptions: {
      title: "Category",
      header: // any custom header here
    }
  },
});

const drawerScreens = createDrawerNavigator({
  Category: CategoryNavigator,
  Products: ProductNavigator,
}, {
  initialRouteName: 'Category'
})


export default AppStack = createStackNavigator({
  drawer: {
    screen: drawerScreens,
  },
  cart: {
    screen: CartScreen
  }
}, {
  initialRouteName: 'drawer',
});

This is the result

Embedded StackNavigator

Following will make a floating header which similar with your screenshot

Set the header mode to float (you don't need to wrap CategoryScreen and ProductScreen into StackNavigator)

export default AppStack = createStackNavigator({
  drawer: {
    screen: drawerScreens,
  },
  cart: {
    screen: CartScreen
  }
}, {
  headerMode: 'float', // set this header mode to float so you can share the header
  initialRouteName: 'drawer',
});

This is the result if you change the header mode to float Float header

Upvotes: 12

Related Questions