RN Lezione 10: Tab e Drawer Navigation
Obiettivi
Section titled “Obiettivi”- Creare navigazione a tab
- Personalizzare barra tab con icone e colori
- Implementare Drawer menu laterale
- Scegliere tra Stack, Tab, Drawer in base all’esigenza
1. Tab Navigator — nav bar in basso
Section titled “1. Tab Navigator — nav bar in basso”Struttura cartelle
Section titled “Struttura cartelle”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)app/(tabs)/_layout.js
Section titled “app/(tabs)/_layout.js”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> );}Schermate per ogni tab
Section titled “Schermate per ogni tab”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> );}2. Combinare Tab + Stack
Section titled “2. Combinare Tab + Stack”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)app/(tabs)/profilo/_layout.js
Section titled “app/(tabs)/profilo/_layout.js”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> );}3. Icone personalizzate
Section titled “3. Icone personalizzate”Per icone più professionali delle emoji:
npx expo install @expo/vector-iconsimport { 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} /> ), }}/>Nomi icone Ionicons comuni
Section titled “Nomi icone Ionicons comuni”"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
4. Drawer Navigator — menu laterale
Section titled “4. Drawer Navigator — menu laterale”npx expo install @react-navigation/drawerStruttura
Section titled “Struttura”app/├── (drawer)/│ ├── _layout.js│ ├── index.js│ └── profilo.js└── _layout.jsapp/(drawer)/_layout.js
Section titled “app/(drawer)/_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> );}5. Quale navigatore usare?
Section titled “5. Quale navigatore usare?”| Tipo | Quando usarlo | Esempio |
|---|---|---|
| Stack | Schermate in sequenza (avanti/indietro) | Lista → Dettaglio |
| Tab | Sezioni principali dell’app | Home, Cerca, Profilo |
| Drawer | Menu ricco con tante voci | Impostazioni, Aiuto, Info |
Pattern comune: Tab + Stack
Section titled “Pattern comune: Tab + Stack”Tab Navigator (esterno)├── Home Tab│ └── Stack Navigator│ ├── Feed│ └── PostDettaglio├── Cerca Tab│ └── Stack│ ├── Ricerca│ └── Risultati└── Profilo Tab └── Stack ├── Profilo └── Modifica6. Tabella riassuntiva
Section titled “6. Tabella riassuntiva”| Navigatore | Cartella | Setup |
|---|---|---|
| Stack | app/_layout.js | <Stack> da expo-router |
| Tab | app/(tabs)/_layout.js | <Tabs> da expo-router |
| Drawer | app/(drawer)/_layout.js | <Drawer> da expo-router/drawer |
7. Esercizio autonomo
Section titled “7. Esercizio autonomo”🎯 Esercizio: “App Comunicazione” con Tab + Stack
Section titled “🎯 Esercizio: “App Comunicazione” con Tab + Stack”Crea un’app con:
- 3 Tab: Home, Chat, Profilo
- Tab Home: titolo + lista notizie fittizie con data
- Tab Chat: FlatList di messaggi + TextInput per scrivere
- Tab Profilo: nome, foto, bio + bottone “Modifica” che apre una schermata stack dentro il tab
- Icone con
@expo/vector-icons(Ionicons) - Tab attivo colorato, inattivo grigio
Struttura
Section titled “Struttura”app/(tabs)/├── _layout.js ← Tab config├── index.js ← Home (notizie)├── chat.js ← Chat (messaggi)└── profilo/ ← Stack dentro tab ├── _layout.js ├── index.js └── modifica.js