Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add extra item at the bottom of the drawer navigation manually (like logout button)?

I want to add logout button to the bottom of the drawer navigation in my RN app.

As you can see the Logout button is located at the bottom of the drawer menu. How can I move it to the bottom of the drawer panel?

I am trying to use contentComponent the following way:

const DrawerWithLogoutButton = (props) => (
  <ScrollView>
    <SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
      <DrawerItems {...props} />
    </SafeAreaView>
    <Button
      style={styles.logoutButton}
      title="Logout"
      onPress={() => props.navigation.navigate('Login') }/>
  </ScrollView>
);

export default Home = createDrawerNavigator({
  // screens
}, {
  // other settings
  contentComponent: DrawerWithLogoutButton,
});

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'column',
  },
  logoutButton: {
    backgroundColor: 'red',
    position: 'absolute',
    bottom: 0
  }
});

In the result I have the Logout button at the bottom of the menu. But I want it to be located at the bottom of the drawer panel instead

Also I would want the Logout button to look like other menu items and had an icon

Is there a way to create drawer navigator with a menu item which has no screen but is just an action like Logout as in my case?

like image 992
Hirurg103 Avatar asked Jun 09 '18 16:06

Hirurg103


4 Answers

I was able to align Logout at the bottom of the drawer menu with adding justifyContent: 'space-between' to the ScrollView container. You can see the result in the picture

the Logout button is located at the bottom of the drawer menu

The result source code looks the following way:

const DrawerWithLogoutButton = (props) => (
  <ScrollView contentContainerStyle={{flex: 1,  flexDirection: 'column', justifyContent: 'space-between' }}>
    <SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
      <DrawerItems {...props} />
    </SafeAreaView>
    <TouchableOpacity>
      <View style={styles.item}>
        <View style={styles.iconContainer}>
          <Image source={require('./img/logout.png')} style={styles.icon}></Image>
        </View>
        <Text style={styles.label}>Logout</Text>
      </View>
    </TouchableOpacity>
  </ScrollView>
);

const styles = StyleSheet.create({
  item: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  label: {
    margin: 16,
    fontWeight: 'bold',
    color: 'rgba(0, 0, 0, .87)',
  },
  iconContainer: {
    marginHorizontal: 16,
    width: 24,
    alignItems: 'center',
  },
  icon: {
    width: 24,
    height: 24,
  }
});
like image 118
Hirurg103 Avatar answered Oct 26 '22 23:10

Hirurg103


React Navigation docs recommend wrapping the drawer navigation with a custom content drawer function. This is what we do did to give our drawer a logout button, but also keep all of the Drawer.Screens in place.

In the code below we create a CustomDrawerContent that contains a DrawerItem as our logout button. This function wraps the Drawer.Navigator through its property drawerContent. Our final drawer then looks like:

  • Home (Drawer.Screen)
  • Edit Profile (Drawer.Screen)
  • Landing (Drawer.Screen)
  • Logout (DrawerItem)
const Drawer = createDrawerNavigator();

function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItemList {...props} />
      <DrawerItem label={() => <Text style={{ color: 'white' }}>Logout</Text>}
        style={{backgroundColor: 'red'}} 
        onPress={() => alert('Logged out')}
      />
    </DrawerContentScrollView>
  );
}

function App(props) {
  return (
    <Provider store={store}>
      <View style={styles.container}>
        <StatusBar translucent={true} />
        <NavigationContainer>
          <Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
            <Drawer.Screen name='Home' component={Home} />
            <Drawer.Screen name='Edit Profile' component={EditProfile} />
            <Drawer.Screen name='Landing' component={Landing} />
          </Drawer.Navigator>
        </NavigationContainer>
      </View>
    </Provider>
  )
}
like image 24
William Griffin Avatar answered Oct 26 '22 22:10

William Griffin


Similar to William Griffins answer, except their answer does not end up with the logout button at the bottom of the drawer. To have logout be at the bottom, I put my DrawerContentScrollView inside a SafeAreaView, then beneath the DrawerContentScrollView I put a regular View containing the DrawerItem, which is the logout button.

function CustomDrawerContent(props) {
    return (
        <SafeAreaView style={{flex: 1}} forceInset={{top: "always", horizontal: "never"}}>
            <DrawerContentScrollView {...props}>
                <DrawerItemList {...props} />
            </DrawerContentScrollView>
            <View>
                <DrawerItem label={"Logout"}
                            style={styles.logoutDrawerItem}
                            onPress={() => console.log('Logout pressed!')}
                />
            </View>
        </SafeAreaView>
    );
}

function App(props) {
  return (
    <Provider store={store}>
      <View style={styles.container}>
        <StatusBar translucent={true} />
        <NavigationContainer>
          <Drawer.Navigator drawerContent={props => <CustomDrawerContent {...props} />}>
            <Drawer.Screen name='Home' component={Home} />
            <Drawer.Screen name='Edit Profile' component={EditProfile} />
            <Drawer.Screen name='Landing' component={Landing} />
          </Drawer.Navigator>
        </NavigationContainer>
      </View>
    </Provider>
  )
}

const styles = StyleSheet.create({
    logoutDrawerItem: {
        borderRadius: 5,
    },
});

Any items you place beneath the DrawerContentScrollView will be placed at the bottom of the drawer.

Note that I set borderRadius to 5 on the logout DrawerItem, so that it closely matches the border radius of regular drawer items.

like image 33
MoreFoam Avatar answered Oct 26 '22 22:10

MoreFoam


You can set position:'absolute' and buttom:0 like this code:

<TouchableOpacity 
    onPress={() => {this.logout()}}
    style={{ bottom: 0, position: 'absolute', width: '100%' }}>
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', flexDirection:'row', alignItems: 'center' }}>
        <Icon name="md-log-out" style={{marginRight: 10, color: '#444'}} size={20}/>
        <Text style={{color: '#444'}}>Logout</Text>
      </View>
</TouchableOpacity>

You can change the style to make it like other buttons. I hope this will help you...

like image 38
Ali SabziNezhad Avatar answered Oct 26 '22 22:10

Ali SabziNezhad