Skip to content

RN Lezione 5: Core Components e StyleSheet

  • Conoscere View, Text, Image, ScrollView
  • Usare StyleSheet per stili separati
  • Gestire ombre, bordi, padding
  • Costruire schermate scrollabili

ComponenteEquivalente WebUso
View<div>Contenitore generico
Text<p> / <span>Testo
TextInput<input>Campo input
Image<img>Immagine
ScrollViewoverflow:scrollContenitore scrollabile
Button<button>Pulsante semplice

View è il mattone fondamentale. Supporta flexbox, stili, eventi.

import { View } from 'react-native';
<View style={{
width: 100,
height: 100,
backgroundColor: 'blue',
borderRadius: 10,
}} />

Tutto il testo DEVE stare dentro <Text>.

// ✅ Corretto
<Text style={{ fontSize: 18 }}>Ciao mondo</Text>
// ❌ SBAGLIATO — testo fuori da Text
<View>Ciao mondo</View>
// Testo annidato (stili ereditati)
<Text style={{ color: 'blue' }}>
Questo è blu
<Text style={{ fontWeight: 'bold' }}> e questo è grassetto</Text>
</Text>

2. StyleSheet — gli stili separati dal markup

Section titled “2. StyleSheet — gli stili separati dal markup”

StyleSheet.create() separa il markup dagli stili (come CSS).

import { StyleSheet, View, Text } from 'react-native';
// --- Markup (JSX) ---
<View style={styles.container}>
<Text style={styles.titolo}>Titolo</Text>
<Text style={styles.testo}>Contenuto</Text>
</View>
// --- Stili (fuori dal componente) ---
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
titolo: {
fontSize: 24,
fontWeight: 'bold',
color: '#333',
marginBottom: 10,
},
testo: {
fontSize: 16,
color: 'grey',
lineHeight: 24,
},
});
Oggetto inlineStyleSheet.create()
<View style={{ padding: 10 }}><View style={styles.container}>
Ricreato a ogni renderUna volta sola
Performance leggermente peggioreOttimizzato
Difficile da riutilizzareFacile da riutilizzare
<View style={styles.base} />
<View style={[styles.base, styles.extra]} /> // Unisce stili
<View style={[styles.base, cond && styles.cond]} /> // Condizionale

padding: 20, // Tutti i lati
paddingHorizontal: 20, // Sinistra + destra
paddingVertical: 10, // Sopra + sotto
paddingTop: 10, // Solo sopra
margin: 20,
marginBottom: 10,
borderWidth: 2,
borderColor: '#ccc',
borderRadius: 12, // Angoli arrotondati
// Solo alcuni angoli:
borderTopLeftRadius: 12,
borderBottomRightRadius: 12,
// iOS
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 8,
// Android
elevation: 4,
fontSize: 18,
fontWeight: 'bold', // 'normal' | 'bold' | '100'-'900'
fontStyle: 'italic', // 'normal' | 'italic'
color: '#333',
textAlign: 'center', // 'left' | 'center' | 'right'
lineHeight: 24, // Altezza riga
letterSpacing: 1, // Spaziatura tra lettere
textTransform: 'uppercase', // 'uppercase' | 'lowercase' | 'capitalize'

import { Image } from 'react-native';
// Immagine da web
<Image
source={{ uri: 'https://picsum.photos/200' }}
style={{ width: 200, height: 200, borderRadius: 100 }}
/>
// Immagine locale
<Image
source={require('./assets/logo.png')}
style={{ width: 100, height: 100 }}
/>
// Con resizeMode
<Image
source={{ uri: 'https://picsum.photos/300/400' }}
style={{ width: '100%', height: 200 }}
resizeMode="cover"
// ↑ 'cover' (default, ritaglia), 'contain' (adatta), 'stretch'
/>

ScrollView permette lo scroll quando il contenuto è più grande dello schermo.

import { ScrollView } from 'react-native';
// Scroll verticale (default)
<ScrollView style={styles.container}>
<Text>Contenuto lungo...</Text>
{/* ... */}
<Text>Fine contenuto</Text>
</ScrollView>
// Scroll orizzontale
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
<View style={{ width: 200, height: 100, backgroundColor: 'red' }} />
<View style={{ width: 200, height: 100, backgroundColor: 'green' }} />
<View style={{ width: 200, height: 100, backgroundColor: 'blue' }} />
</ScrollView>
ProprietàDescrizione
horizontalScroll orizzontale (default: verticale)
showsVerticalScrollIndicatorMostra barra scroll verticale
showsHorizontalScrollIndicatorMostra barra scroll orizzontale
contentContainerStyleStili per il contenitore interno
pagingEnabledScroll a pagina intera (come iOS springboard)

6. Esempio guidato: Pagina profilo scrollabile

Section titled “6. Esempio guidato: Pagina profilo scrollabile”
import { View, Text, Image, ScrollView, StyleSheet } from 'react-native';
export default function App() {
return (
<ScrollView style={styles.container}>
{/* Header con foto copertina */}
<View style={styles.header}>
<Image
source={{ uri: 'https://picsum.photos/seed/copertina/400/200' }}
style={styles.copertina}
/>
<Image
source={{ uri: 'https://i.pravatar.cc/150?u=mario' }}
style={styles.avatar}
/>
</View>
{/* Info profilo */}
<View style={styles.section}>
<Text style={styles.nome}>Mario Rossi</Text>
<Text style={styles.ruolo}>💻 Sviluppatore mobile</Text>
<Text style={styles.bio}>
Studente di Informatica, appassionato di React Native e sviluppo mobile.
Amo creare app che funzionano su Android e iOS.
</Text>
</View>
{/* Statistiche */}
<View style={styles.statsRow}>
<View style={styles.stat}>
<Text style={styles.statNumero}>42</Text>
<Text style={styles.statLabel}>Progetti</Text>
</View>
<View style={styles.stat}>
<Text style={styles.statNumero}>15</Text>
<Text style={styles.statLabel}>App pubblicate</Text>
</View>
<View style={styles.stat}>
<Text style={styles.statNumero}>3</Text>
<Text style={styles.statLabel}>Linguaggi</Text>
</View>
</View>
{/* Competenze */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>⚡ Competenze</Text>
{['React Native', 'Python', 'JavaScript', 'Flet', 'Git'].map((skill, i) => (
<View key={i} style={styles.skillRow}>
<Text style={styles.skillNome}>{skill}</Text>
<View style={styles.skillBar}>
<View style={[styles.skillFill, { width: `${(5 - i) * 25}%` }]} />
</View>
</View>
))}
</View>
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f0f4f8',
},
header: {
alignItems: 'center',
marginBottom: 20,
},
copertina: {
width: '100%',
height: 150,
},
avatar: {
width: 100,
height: 100,
borderRadius: 50,
marginTop: -50,
borderWidth: 4,
borderColor: 'white',
},
section: {
backgroundColor: 'white',
marginHorizontal: 15,
marginBottom: 15,
padding: 20,
borderRadius: 15,
elevation: 2,
shadowColor: '#000',
shadowOpacity: 0.05,
shadowRadius: 5,
},
nome: {
fontSize: 22,
fontWeight: 'bold',
textAlign: 'center',
},
ruolo: {
fontSize: 14,
color: 'grey',
textAlign: 'center',
marginBottom: 10,
},
bio: {
fontSize: 14,
color: '#555',
lineHeight: 22,
textAlign: 'center',
},
statsRow: {
flexDirection: 'row',
justifyContent: 'space-around',
backgroundColor: 'white',
marginHorizontal: 15,
marginBottom: 15,
padding: 15,
borderRadius: 15,
elevation: 2,
},
stat: {
alignItems: 'center',
},
statNumero: {
fontSize: 24,
fontWeight: 'bold',
color: '#3498db',
},
statLabel: {
fontSize: 12,
color: 'grey',
},
sectionTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 15,
},
skillRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 10,
},
skillNome: {
width: 100,
fontSize: 14,
color: '#555',
},
skillBar: {
flex: 1,
height: 8,
backgroundColor: '#e0e0e0',
borderRadius: 4,
overflow: 'hidden',
},
skillFill: {
height: '100%',
backgroundColor: '#3498db',
borderRadius: 4,
},
});

<View style={styles.card}>
<Image source={{ uri: 'https://picsum.photos/seed/1/300/200' }}
style={styles.cardImg} />
<View style={styles.cardBody}>
<Text style={styles.cardTitolo}>Prodotto</Text>
<Text style={styles.cardPrezzo}>€ 12.99</Text>
</View>
</View>
<View style={{ height: 1, backgroundColor: '#eee', marginVertical: 15 }} />
<View style={styles.badge}>
<Text style={styles.badgeTesto}>Nuovo</Text>
</View>

ComponenteCodice minimo
View<View style={...} />
Text<Text style={...}>testo</Text>
Image<Image source={{uri: '...'}} style={...} />
ScrollView<ScrollView>...</ScrollView>
StyleSheetconst s = StyleSheet.create({...})

🎯 Esercizio: “Galleria prodotti scrollabile”

Section titled “🎯 Esercizio: “Galleria prodotti scrollabile””

Crea una schermata scrollabile con:

  1. Header con titolo e sfondo colorato
  2. Almeno 4 card prodotto, ognuna con:
    • Immagine (https://picsum.photos/seed/PRODOTTO/300/200)
    • Nome prodotto (grassetto, 18px)
    • Prezzo (verde, 16px)
    • Descrizione (grigio, 14px)
  3. Card con angoli arrotondati, ombra, margine
  4. ScrollView per scrollare tutto
const PRODOTTI = [
{ id: 1, nome: 'Pizza Margherita', prezzo: 6.50, desc: 'Pomodoro, mozzarella, basilico' },
{ id: 2, nome: 'Pasta Carbonara', prezzo: 8.00, desc: 'Uova, guanciale, pecorino' },
{ id: 3, nome: 'Insalata Greca', prezzo: 5.50, desc: 'Feta, olive, cetrioli' },
{ id: 4, nome: 'Tiramisù', prezzo: 4.00, desc: 'Mascarpone, caffè, cacao' },
];