Kurs React Native · Moduł 3: Nawigacja
Tab Navigation - Zakładki Podwodnego Menu
W tej lekcji7
W pałacu Atlantydy znajduje się główne menu z zakładkami, pozwalające szybko przemieszczać się między głównymi sekcjami. To właśnie Tab Navigation!
Instalacja Tab Navigator
npx expo install @react-navigation/bottom-tabsPodstawowy Tab Navigator
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
type TabParamList = {
Home: undefined;
Search: undefined;
Profile: undefined;
Settings: undefined;
};
const Tab = createBottomTabNavigator<TabParamList>();
function MainTabs() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName: keyof typeof Ionicons.glyphMap;
switch (route.name) {
case 'Home':
iconName = focused ? 'home' : 'home-outline';
break;
case 'Search':
iconName = focused ? 'search' : 'search-outline';
break;
case 'Profile':
iconName = focused ? 'person' : 'person-outline';
break;
case 'Settings':
iconName = focused ? 'settings' : 'settings-outline';
break;
default:
iconName = 'ellipse';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#1a5276',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Search" component={SearchScreen} />
<Tab.Screen name="Profile" component={ProfileScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}Stylowanie Tab Bar
<Tab.Navigator
screenOptions={{
tabBarStyle: {
backgroundColor: '#0a2e4a',
borderTopWidth: 0,
elevation: 10,
height: 60,
paddingBottom: 8,
paddingTop: 8,
},
tabBarActiveTintColor: '#00d4ff',
tabBarInactiveTintColor: '#6c7a89',
tabBarLabelStyle: {
fontSize: 12,
fontWeight: '600',
},
headerStyle: {
backgroundColor: '#0a2e4a',
},
headerTintColor: '#fff',
}}
>
{/* Screens */}
</Tab.Navigator>Badge na zakładce
<Tab.Screen
name="Notifications"
component={NotificationsScreen}
options={{
tabBarBadge: 3, // Pokazuje badge z liczbą
tabBarBadgeStyle: {
backgroundColor: '#ff6b6b',
color: '#fff',
},
}}
/>Ukrywanie Tab Bar na niektórych ekranach
// W komponencie ekranu
import { useLayoutEffect } from 'react';
function DetailsScreen({ navigation }) {
useLayoutEffect(() => {
navigation.getParent()?.setOptions({
tabBarStyle: { display: 'none' },
});
return () => {
navigation.getParent()?.setOptions({
tabBarStyle: { display: 'flex' },
});
};
}, [navigation]);
return <View>{/* content */}</View>;
}Zagnieżdżanie Stack w Tab
// Każda zakładka może mieć własny Stack Navigator
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="HomeMain" component={HomeScreen} />
<Stack.Screen name="HomeDetails" component={DetailsScreen} />
</Stack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeStack}
options={{ headerShown: false }} // Ukryj nagłówek Tab, Stack ma własny
/>
<Tab.Screen name="Profile" component={ProfileStack} />
</Tab.Navigator>
</NavigationContainer>
);
}Top Tabs (Material Top Tabs)
npx expo install @react-navigation/material-top-tabs react-native-pager-viewimport { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
const TopTab = createMaterialTopTabNavigator();
function ProfileTabs() {
return (
<TopTab.Navigator
screenOptions={{
tabBarLabelStyle: { fontSize: 14, fontWeight: 'bold' },
tabBarStyle: { backgroundColor: '#0a2e4a' },
tabBarActiveTintColor: '#00d4ff',
tabBarIndicatorStyle: { backgroundColor: '#00d4ff' },
}}
>
<TopTab.Screen name="Posts" component={PostsScreen} />
<TopTab.Screen name="Photos" component={PhotosScreen} />
<TopTab.Screen name="Likes" component={LikesScreen} />
</TopTab.Navigator>
);
}Tab Navigation idealnie nadaje się do głównych sekcji aplikacji. Użytkownicy oczekują jej na dole ekranu (iOS) lub na górze (Android Material Design).
Kod do tej lekcji: App.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
const Tab = createBottomTabNavigator();
function Screen({ label }) {
return (
<View style={styles.screen}>
<Text style={styles.title}>{label}</Text>
</View>
);
}
const HomeScreen = () => <Screen label="Główna Sala" />;
const MapScreen = () => <Screen label="Mapa Głębin" />;
const ProfileScreen = () => <Screen label="Profil Trytona" />;
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
{/* TODO: dodaj zakładkę "Home" z component={HomeScreen} */}
{/* W options ustaw tabBarIcon: ({ color, size }) => <Ionicons name="home" size={size} color={color} /> */}
{/* TODO: dodaj zakładkę "Map" (component={MapScreen}, ikona "map") */}
{/* TODO: dodaj zakładkę "Profile" (component={ProfileScreen}, ikona "person") */}
</Tab.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
screen: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1a5276',
},
title: {
fontSize: 22,
color: '#fff',
fontWeight: '600',
},
});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óra biblioteka służy do tworzenia dolnych zakładek?
2. Która właściwość dodaje badge (liczbę powiadomień) na zakładce?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w poziomie
Ułóż poprawną strukturę tabBarIcon:
- Edytor kodu
Uzupełnij kod Tab Navigator.