Kurs React Native · Moduł 3: Nawigacja
Drawer Navigation - Boczne Menu Pałacu
W tej lekcji7
Drawer Navigation to wysuwane boczne menu, idealne dla aplikacji z wieloma sekcjami lub ustawieniami.
Instalacja
npx expo install @react-navigation/drawer
npx expo install react-native-gesture-handler react-native-reanimatedKonfiguracja babel.config.js
// babel.config.js
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: ['react-native-reanimated/plugin'], // Musi być ostatni!
};
};Podstawowy Drawer
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: 'Strona główna',
}}
/>
<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>
);
}Niestandardowa zawartość Drawer
import {
DrawerContentScrollView,
DrawerItemList,
DrawerItem
} from '@react-navigation/drawer';
function CustomDrawerContent(props: DrawerContentComponentProps) {
const { navigation } = props;
return (
<DrawerContentScrollView {...props}>
{/* Nagłówek z profilem użytkownika */}
<View style={styles.drawerHeader}>
<Image
source={{ uri: 'https://example.com/avatar.jpg' }}
style={styles.avatar}
/>
<Text style={styles.username}>Posejdon</Text>
<Text style={styles.email}>posejdon@atlantyda.sea</Text>
</View>
{/* Separator */}
<View style={styles.separator} />
{/* Domyślna lista ekranów */}
<DrawerItemList {...props} />
{/* Separator */}
<View style={styles.separator} />
{/* Dodatkowe elementy */}
<DrawerItem
label="Pomoc"
icon={({ color, size }) => (
<Ionicons name="help-circle" size={size} color={color} />
)}
onPress={() => {
// Własna akcja
alert('Centrum pomocy Atlantydy');
}}
/>
<DrawerItem
label="Wyloguj"
icon={({ color, size }) => (
<Ionicons name="log-out" size={size} color={color} />
)}
onPress={() => {
// Logika wylogowania
navigation.closeDrawer();
}}
/>
</DrawerContentScrollView>
);
}
// Użycie
<Drawer.Navigator
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
{/* Screens */}
</Drawer.Navigator>Otwieranie/zamykanie Drawer programowo
import { useNavigation, DrawerActions } from '@react-navigation/native';
function HomeScreen() {
const navigation = useNavigation();
return (
<View>
<Pressable onPress={() => navigation.dispatch(DrawerActions.openDrawer())}>
<Text>Otwórz menu</Text>
</Pressable>
<Pressable onPress={() => navigation.dispatch(DrawerActions.closeDrawer())}>
<Text>Zamknij menu</Text>
</Pressable>
<Pressable onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}>
<Text>Przełącz menu</Text>
</Pressable>
</View>
);
}Drawer z prawej strony
<Drawer.Navigator
screenOptions={{
drawerPosition: 'right', // Domyślnie 'left'
}}
>
{/* Screens */}
</Drawer.Navigator>Zagnieżdżanie nawigatorów
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 świetnie sprawdza się w aplikacjach z wieloma sekcjami, panelach administracyjnych i aplikacjach korporacyjnych.
Kod do tej lekcji: App.tsx
import React from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import {
DrawerContentScrollView,
DrawerItemList,
} from '@react-navigation/drawer';
// Niestandardowa zawartość szuflady (Drawer) z nagłówkiem profilu
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
{/* TODO: dodaj nagłówek profilu w <View style={styles.header}>:
- <Image style={styles.avatar} source={{ uri: 'https://i.pravatar.cc/100' }} />
- <Text style={styles.name}>Posejdon</Text> */}
{/* TODO: poniżej nagłówka wyrenderuj domyślną listę pozycji: <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;Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Które biblioteki są wymagane dla Drawer Navigator?
2. Jak ustawić Drawer po prawej stronie ekranu?
Zadania praktyczne w grze
- Klikanie w kolejności
Kliknij elementy otwierania Drawer programowo:
- Edytor kodu
Uzupełnij kod CustomDrawerContent.