Kurs React Native · Moduł 3: Nawigacja

Tab Navigation - Zakładki Podwodnego Menu

3 min czytania ·
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-tabs

Podstawowy 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-view
import { 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. 1. Która biblioteka służy do tworzenia dolnych zakładek?

  2. 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.

Przydatne artykuły