Skip to content

RN Lezione 10: Tab e Drawer Navigation

  • Creare navigazione a tab
  • Personalizzare barra tab con icone e colori
  • Implementare Drawer menu laterale
  • Scegliere tra Stack, Tab, Drawer in base all’esigenza

app/
├── (tabs)/ ← Cartella speciale per tab
│ ├── _layout.js ← Configurazione tab
│ ├── index.js ← Tab Home (route: /)
│ ├── cerca.js ← Tab Cerca (route: /cerca)
│ └── profilo.js ← Tab Profilo (route: /profilo)
└── _layout.js ← Stack radice (se serve)
import { Tabs } from 'expo-router';
import { Text } from 'react-native';
export default function TabLayout() {
return (
<Tabs
screenOptions={{
tabBarActiveTintColor: '#3498db', // Colore tab attivo
tabBarInactiveTintColor: '#999', // Colore tab inattivo
tabBarStyle: {
backgroundColor: 'white',
borderTopWidth: 1,
borderTopColor: '#eee',
height: 60,
},
tabBarLabelStyle: {
fontSize: 12,
marginBottom: 5,
},
}}
>
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color, size }) => (
<Text style={{ fontSize: size }}>🏠</Text>
),
}}
/>
<Tabs.Screen
name="cerca"
options={{
title: 'Cerca',
tabBarIcon: ({ color, size }) => (
<Text style={{ fontSize: size }}>🔍</Text>
),
}}
/>
<Tabs.Screen
name="profilo"
options={{
title: 'Profilo',
tabBarIcon: ({ color, size }) => (
<Text style={{ fontSize: size }}>👤</Text>
),
}}
/>
</Tabs>
);
}

app/(tabs)/index.js

import { View, Text } from 'react-native';
export default function Home() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ fontSize: 48 }}>🏠</Text>
<Text style={{ fontSize: 18 }}>Home</Text>
</View>
);
}

app/(tabs)/cerca.js

import { View, Text, TextInput } from 'react-native';
export default function Cerca() {
return (
<View style={{ flex: 1, padding: 20 }}>
<TextInput
style={{
borderWidth: 1,
borderColor: '#ddd',
padding: 12,
borderRadius: 10,
fontSize: 16,
marginTop: 50,
}}
placeholder="Cerca..."
/>
</View>
);
}

Spesso si vuole un Tab navigator esterno con Stack interni in ogni tab.

app/
├── (tabs)/
│ ├── _layout.js ← Layout TAB
│ ├── index.js ← Tab Home
│ ├── cerca.js ← Tab Cerca
│ ├── profilo/
│ │ ├── _layout.js ← Stack dentro Profilo tab
│ │ ├── index.js ← Schermata profilo
│ │ └── modifica.js ← Schermata modifica profilo
│ └── _layout.js
└── _layout.js ← Stack globale (se serve)
import { Stack } from 'expo-router';
export default function ProfiloLayout() {
return (
<Stack>
<Stack.Screen name="index" options={{ title: 'Profilo' }} />
<Stack.Screen name="modifica" options={{ title: 'Modifica profilo' }} />
</Stack>
);
}

Per icone più professionali delle emoji:

Terminal window
npx expo install @expo/vector-icons
import { Ionicons } from '@expo/vector-icons';
<Tabs.Screen
name="index"
options={{
title: 'Home',
tabBarIcon: ({ color, size }) => (
<Ionicons name="home" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="cerca"
options={{
title: 'Cerca',
tabBarIcon: ({ color, size }) => (
<Ionicons name="search" size={size} color={color} />
),
}}
/>
<Tabs.Screen
name="profilo"
options={{
title: 'Profilo',
tabBarIcon: ({ color, size }) => (
<Ionicons name="person" size={size} color={color} />
),
}}
/>
"home" "search" "person" "settings"
"heart" "star" "cart" "book"
"create" "trash" "checkmark" "close"
"arrow-back" "add" "information-circle"

Vedi tutti i nomi su icons.expo.fyi


Terminal window
npx expo install @react-navigation/drawer
app/
├── (drawer)/
│ ├── _layout.js
│ ├── index.js
│ └── profilo.js
└── _layout.js
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { Drawer } from 'expo-router/drawer';
export default function DrawerLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Drawer
screenOptions={{
drawerActiveTintColor: '#3498db',
drawerInactiveTintColor: '#555',
drawerStyle: {
backgroundColor: 'white',
width: 280,
},
drawerLabelStyle: {
fontSize: 16,
},
}}
>
<Drawer.Screen
name="index"
options={{
title: 'Home',
drawerIcon: ({ color, size }) => <Ionicons name="home" size={size} color={color} />,
}}
/>
<Drawer.Screen
name="profilo"
options={{
title: 'Profilo',
drawerIcon: ({ color, size }) => <Ionicons name="person" size={size} color={color} />,
}}
/>
</Drawer>
</GestureHandlerRootView>
);
}

TipoQuando usarloEsempio
StackSchermate in sequenza (avanti/indietro)Lista → Dettaglio
TabSezioni principali dell’appHome, Cerca, Profilo
DrawerMenu ricco con tante vociImpostazioni, Aiuto, Info
Tab Navigator (esterno)
├── Home Tab
│ └── Stack Navigator
│ ├── Feed
│ └── PostDettaglio
├── Cerca Tab
│ └── Stack
│ ├── Ricerca
│ └── Risultati
└── Profilo Tab
└── Stack
├── Profilo
└── Modifica

NavigatoreCartellaSetup
Stackapp/_layout.js<Stack> da expo-router
Tabapp/(tabs)/_layout.js<Tabs> da expo-router
Drawerapp/(drawer)/_layout.js<Drawer> da expo-router/drawer

🎯 Esercizio: “App Comunicazione” con Tab + Stack

Section titled “🎯 Esercizio: “App Comunicazione” con Tab + Stack”

Crea un’app con:

  1. 3 Tab: Home, Chat, Profilo
  2. Tab Home: titolo + lista notizie fittizie con data
  3. Tab Chat: FlatList di messaggi + TextInput per scrivere
  4. Tab Profilo: nome, foto, bio + bottone “Modifica” che apre una schermata stack dentro il tab
  5. Icone con @expo/vector-icons (Ionicons)
  6. Tab attivo colorato, inattivo grigio
app/(tabs)/
├── _layout.js ← Tab config
├── index.js ← Home (notizie)
├── chat.js ← Chat (messaggi)
└── profilo/ ← Stack dentro tab
├── _layout.js
├── index.js
└── modifica.js