Cours React Native · Module 3: Navigation

Drawer Navigation - Le menu latéral du palais

3 min de lecture ·
Dans cette leçon7

Drawer Navigation est un menu latéral coulissant, parfait pour les applications comportant de nombreuses sections ou de nombreux réglages.

Installation

npx expo install @react-navigation/drawer
npx expo install react-native-gesture-handler react-native-reanimated

Configurer babel.config.js

// babel.config.js
module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    plugins: ['react-native-reanimated/plugin'], // Doit être en dernier !
  };
};

Drawer de base

import { createDrawerNavigator } from '@react-navigation/drawer';
import { Ionicons } from '@expo/vector-icons';

type DrawerParamList = {
  Home: undefined;
  Profile: undefined;
  Settings: undefined;
  Help: undefined;
};

const Drawer = createDrawerNavigator<DrawerParamList>();

function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator
        screenOptions={{
          drawerStyle: {
            backgroundColor: '#0a2e4a',
            width: 280,
          },
          drawerActiveTintColor: '#00d4ff',
          drawerInactiveTintColor: '#a0aec0',
          drawerLabelStyle: {
            marginLeft: -20,
            fontSize: 16,
          },
          headerStyle: {
            backgroundColor: '#0a2e4a',
          },
          headerTintColor: '#fff',
        }}
      >
        <Drawer.Screen
          name="Home"
          component={HomeScreen}
          options={{
            drawerIcon: ({ color, size }) => (
              <Ionicons name="home" size={size} color={color} />
            ),
            drawerLabel: 'Page d\'accueil',
          }}
        />
        <Drawer.Screen
          name="Profile"
          component={ProfileScreen}
          options={{
            drawerIcon: ({ color, size }) => (
              <Ionicons name="person" size={size} color={color} />
            ),
          }}
        />
        <Drawer.Screen
          name="Settings"
          component={SettingsScreen}
          options={{
            drawerIcon: ({ color, size }) => (
              <Ionicons name="settings" size={size} color={color} />
            ),
          }}
        />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

Contenu de Drawer personnalisé

import {
  DrawerContentScrollView,
  DrawerItemList,
  DrawerItem
} from '@react-navigation/drawer';

function CustomDrawerContent(props: DrawerContentComponentProps) {
  const { navigation } = props;

  return (
    <DrawerContentScrollView {...props}>
      {/* En-tête avec le profil de l'utilisateur */}
      <View style={styles.drawerHeader}>
        <Image
          source={{ uri: 'https://example.com/avatar.jpg' }}
          style={styles.avatar}
        />
        <Text style={styles.username}>Poséidon</Text>
        <Text style={styles.email}>poseidon@atlantis.sea</Text>
      </View>

      {/* Séparateur */}
      <View style={styles.separator} />

      {/* Liste d'écrans par défaut */}
      <DrawerItemList {...props} />

      {/* Séparateur */}
      <View style={styles.separator} />

      {/* Éléments supplémentaires */}
      <DrawerItem
        label="Aide"
        icon={({ color, size }) => (
          <Ionicons name="help-circle" size={size} color={color} />
        )}
        onPress={() => {
          // Action personnalisée
          alert('Centre d\'aide d\'Atlantis');
        }}
      />

      <DrawerItem
        label="Se déconnecter"
        icon={({ color, size }) => (
          <Ionicons name="log-out" size={size} color={color} />
        )}
        onPress={() => {
          // Logique de déconnexion
          navigation.closeDrawer();
        }}
      />
    </DrawerContentScrollView>
  );
}

// Utilisation
<Drawer.Navigator
  drawerContent={(props) => <CustomDrawerContent {...props} />}
>
  {/* Écrans */}
</Drawer.Navigator>

Ouvrir/fermer le Drawer par programmation

import { useNavigation, DrawerActions } from '@react-navigation/native';

function HomeScreen() {
  const navigation = useNavigation();

  return (
    <View>
      <Pressable onPress={() => navigation.dispatch(DrawerActions.openDrawer())}>
        <Text>Ouvrir le menu</Text>
      </Pressable>

      <Pressable onPress={() => navigation.dispatch(DrawerActions.closeDrawer())}>
        <Text>Fermer le menu</Text>
      </Pressable>

      <Pressable onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}>
        <Text>Basculer le menu</Text>
      </Pressable>
    </View>
  );
}

Drawer sur le côté droit

<Drawer.Navigator
  screenOptions={{
    drawerPosition: 'right', // Par défaut, c'est 'left'
  }}
>
  {/* Écrans */}
</Drawer.Navigator>

Imbriquer des navigateurs

function MainStack() {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name="MainTabs"
        component={MainTabs}
        options={{ headerShown: false }}
      />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen
          name="Main"
          component={MainStack}
          options={{ headerShown: false }}
        />
        <Drawer.Screen name="Settings" component={SettingsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

Drawer Navigation fonctionne à merveille dans les applications comportant de nombreuses sections, les panneaux d'administration et les applications d'entreprise.

Code de cette leçon : App.tsx
import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import {
  DrawerContentScrollView,
  DrawerItemList,
} from '@react-navigation/drawer';

// Contenu de Drawer personnalisé avec un en-tête de profil
function CustomDrawerContent(props) {
  return (
    <DrawerContentScrollView {...props}>
      {/* TODO : ajoute un en-tête de profil dans <View style={styles.header}> :
          - <Image style={styles.avatar} source={{ uri: 'https://i.pravatar.cc/100' }} />
          - <Text style={styles.name}>Poséidon</Text> */}

      {/* TODO : sous l'en-tête, affiche la liste d'éléments par défaut : <DrawerItemList {...props} /> */}

    </DrawerContentScrollView>
  );
}

const styles = StyleSheet.create({
  header: {
    padding: 20,
    alignItems: 'center',
    backgroundColor: '#1a5276',
    marginBottom: 8,
  },
  avatar: {
    width: 72,
    height: 72,
    borderRadius: 36,
    marginBottom: 10,
  },
  name: {
    color: '#fff',
    fontSize: 18,
    fontWeight: '600',
  },
});

export default CustomDrawerContent;

Entrées de la documentation utilisées dans cette leçon

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quelles bibliothèques sont requises pour le Drawer Navigator ?

  2. 2. Comment place-t-on le Drawer sur le côté droit de l'écran ?

Tâches pratiques dans le jeu

  • Clique dans l'ordre

    Clique sur les éléments pour ouvrir un Drawer par programmation :

  • Éditeur de code

    Complète le code de CustomDrawerContent.

Articles utiles