RN Lez 11: Flex, Spazio e Griglie
Docs: Flexbox, Layout Props
Obiettivi
Section titled “Obiettivi”- Usare flex per dividere spazio equamente
- Creare griglie con flexWrap
- Usare gap per spazi tra elementi
1. Flex — dividere lo spazio
Section titled “1. Flex — dividere lo spazio”flex è un rapporto: indica quanto spazio occupa un elemento rispetto agli altri.
<View style={{ flex: 1, backgroundColor: 'red' }} /> {/* 1/4 */}<View style={{ flex: 2, backgroundColor: 'green' }} /> {/* 2/4 */}<View style={{ flex: 1, backgroundColor: 'blue' }} /> {/* 1/4 */}┌──────┬──────────────────────┬──────┐│ red │ green │ blue ││ 1/4 │ 2/4 │ 1/4 │└──────┴──────────────────────┴──────┘Layout comune: sidebar + content
Section titled “Layout comune: sidebar + content”<View style={{ flex: 1, flexDirection: 'row' }}> <View style={{ flex: 1, backgroundColor: '#eee' }}> {/* sidebar 1/3 */} <View style={{ flex: 2, backgroundColor: 'white' }}> {/* content 2/3 */}</View>2. flexWrap — andare a capo
Section titled “2. flexWrap — andare a capo”Permette di creare griglie responsive.
<View style={{ flexDirection: 'row', flexWrap: 'wrap', // ← va a capo justifyContent: 'space-between',}}> <View style={{ width: '48%', height: 100, backgroundColor: 'red' }} /> <View style={{ width: '48%', height: 100, backgroundColor: 'green' }} /> <View style={{ width: '48%', height: 100, backgroundColor: 'blue' }} /> <View style={{ width: '48%', height: 100, backgroundColor: 'orange' }} /></View>┌────────┐ ┌────────┐│ red │ │ green │└────────┘ └────────┘┌────────┐ ┌────────┐│ blue │ │ orange │└────────┘ └────────┘3. Gap — spazio tra elementi
Section titled “3. Gap — spazio tra elementi”React Native 0.71+ supporta gap, rowGap, columnGap.
<View style={{ flexDirection: 'row', gap: 10 }}> <Item /> <Item /> <Item /></View>Prima di 0.71 si usava margin su ogni elemento (tranne l’ultimo).
4. Griglia di card con flexWrap + gap
Section titled “4. Griglia di card con flexWrap + gap”type Prodotto = { nome: string; prezzo: number; img: string;};
const Card = ({ nome, prezzo, img }: Prodotto) => ( <View style={styles.card}> <Image source={{ uri: img }} style={styles.img} /> <Text style={styles.nome}>{nome}</Text> <Text style={styles.prezzo}>€{prezzo.toFixed(2)}</Text> </View>);
const PRODOTTI: Prodotto[] = [ { nome: 'Pizza', prezzo: 6.50, img: 'https://picsum.photos/seed/p1/200' }, { nome: 'Pasta', prezzo: 8.00, img: 'https://picsum.photos/seed/p2/200' }, { nome: 'Insalata', prezzo: 5.50, img: 'https://picsum.photos/seed/p3/200' }, { nome: 'Dolce', prezzo: 4.00, img: 'https://picsum.photos/seed/p4/200' },];
export default function App() { return ( <View style={styles.container}> <View style={styles.griglia}> {PRODOTTI.map((p, i) => <Card key={i} {...p} />)} </View> </View> );}
const styles = StyleSheet.create({ container: { flex: 1, padding: 10, backgroundColor: '#f0f4f8' }, griglia: { flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between', gap: 10, }, card: { width: '48%', backgroundColor: 'white', borderRadius: 12, padding: 12, elevation: 2, }, img: { width: '100%', height: 120, borderRadius: 8, marginBottom: 8 }, nome: { fontSize: 16, fontWeight: 'bold' }, prezzo: { fontSize: 18, color: '#2ecc71', fontWeight: 'bold', marginTop: 4 },});5. Tabella riassuntiva
Section titled “5. Tabella riassuntiva”| Proprietà | Valori | Descrizione |
|---|---|---|
flex | numero (1, 2, …) | Rapporto spazio |
flexWrap | 'wrap', 'nowrap' | Vai a capo? |
gap | numero | Spazio tra elementi |
rowGap | numero | Gap righe |
columnGap | numero | Gap colonne |
6. Esercizio
Section titled “6. Esercizio”🎯 “Griglia menu ristorante”
Section titled “🎯 “Griglia menu ristorante””Crea una griglia 2×N con flexWrap:
- Ogni card: immagine in alto, nome sotto, prezzo
- Larghezza ~48%
- Header con nome ristorante in alto
- Almeno 4 piatti