Cours React Native · Module 2: Listes et styles
StyleSheet - Stylage avancé
Dans cette leçon4
StyleSheet est la base du stylage dans React Native. Explorons les techniques avancées !
Créer des styles
import { View, Text, StyleSheet } from 'react-native';
export default function StyleExample() {
return (
<View style={styles.container}>
{/* Style unique */}
<Text style={styles.title}>Titre</Text>
{/* Combiner des styles (tableau) */}
<Text style={[styles.text, styles.bold]}>Texte en gras</Text>
{/* Styles conditionnels */}
<Text style={[styles.text, isActive && styles.active]}>
Style conditionnel
</Text>
{/* Inline + StyleSheet */}
<Text style={[styles.text, { color: 'red' }]}>
Surcharge inline
</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
text: {
fontSize: 16,
},
bold: {
fontWeight: 'bold',
},
active: {
color: '#3498db',
},
});Flexbox dans React Native
Flexbox fonctionne de manière similaire à CSS, mais avec quelques différences :
import { View, Text, StyleSheet } from 'react-native';
export default function FlexboxExample() {
return (
<View style={styles.container}>
{/* Flex direction - column par défaut ! */}
<View style={styles.column}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3} />
</View>
{/* Direction row */}
<View style={styles.row}>
<View style={styles.box1} />
<View style={styles.box2} />
<View style={styles.box3} />
</View>
{/* Flex grow */}
<View style={styles.row}>
<View style={[styles.box1, { flex: 1 }]} />
<View style={[styles.box2, { flex: 2 }]} />
<View style={[styles.box3, { flex: 1 }]} />
</View>
{/* Justify & Align */}
<View style={styles.centered}>
<Text style={styles.text}>Centré</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
gap: 20,
backgroundColor: '#1a5276',
},
column: {
flexDirection: 'column', // Par défaut dans RN
gap: 10,
},
row: {
flexDirection: 'row',
gap: 10,
},
centered: {
flex: 1,
justifyContent: 'center', // Axe principal
alignItems: 'center', // Axe transversal
backgroundColor: '#2c3e50',
borderRadius: 12,
},
box1: {
width: 60,
height: 60,
backgroundColor: '#e74c3c',
borderRadius: 8,
},
box2: {
width: 60,
height: 60,
backgroundColor: '#2ecc71',
borderRadius: 8,
},
box3: {
width: 60,
height: 60,
backgroundColor: '#3498db',
borderRadius: 8,
},
text: {
color: '#fff',
fontSize: 18,
},
});Position: absolute
import { View, Text, StyleSheet } from 'react-native';
export default function PositionExample() {
return (
<View style={styles.container}>
<View style={styles.card}>
<Text style={styles.cardTitle}>Carte de trésor</Text>
{/* Badge dans le coin supérieur droit */}
<View style={styles.badge}>
<Text style={styles.badgeText}>NOUVEAU</Text>
</View>
{/* Icône dans le coin inférieur gauche */}
<View style={styles.icon}>
<Text>◆</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#1a5276',
},
card: {
width: 250,
height: 150,
backgroundColor: '#2c3e50',
borderRadius: 16,
padding: 20,
},
cardTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#fff',
},
badge: {
position: 'absolute',
top: -10,
right: -10,
backgroundColor: '#e74c3c',
paddingHorizontal: 10,
paddingVertical: 4,
borderRadius: 12,
},
badgeText: {
color: '#fff',
fontSize: 12,
fontWeight: 'bold',
},
icon: {
position: 'absolute',
bottom: 10,
left: 10,
width: 40,
height: 40,
backgroundColor: '#f39c12',
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
},
});Ombres
import { View, Text, StyleSheet, Platform } from 'react-native';
export default function ShadowExample() {
return (
<View style={styles.container}>
{/* Ombre iOS */}
<View style={styles.cardIOS}>
<Text style={styles.text}>Ombre iOS</Text>
</View>
{/* Ombre Android (elevation) */}
<View style={styles.cardAndroid}>
<Text style={styles.text}>Elevation Android</Text>
</View>
{/* Ombre multiplateforme */}
<View style={styles.cardCrossplatform}>
<Text style={styles.text}>Multiplateforme</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
gap: 30,
backgroundColor: '#ecf0f1',
},
cardIOS: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// iOS uniquement
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
},
cardAndroid: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// Android uniquement
elevation: 8,
},
cardCrossplatform: {
width: 200,
padding: 20,
backgroundColor: '#fff',
borderRadius: 12,
// Les deux plateformes
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.3,
shadowRadius: 8,
},
android: {
elevation: 8,
},
}),
},
text: {
textAlign: 'center',
fontSize: 16,
},
});Code de cette leçon : App.tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<View style={styles.card}>
<Text style={styles.emoji}>{'><>'}</Text>
<Text style={styles.name}>Poisson de corail</Text>
<Text style={styles.description}>Habitant des récifs de l'Atlantide</Text>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#aed6f1',
},
card: {
width: 220,
padding: 20,
backgroundColor: '#fff',
alignItems: 'center',
// TODO : ajoute borderRadius: 16 pour arrondir les coins de la carte
// TODO : ajoute l'ombre iOS :
// shadowColor: '#000',
// shadowOffset: { width: 0, height: 4 },
// shadowOpacity: 0.25,
// shadowRadius: 8,
// TODO : ajoute l'ombre Android : elevation: 8,
},
emoji: {
fontSize: 48,
marginBottom: 8,
},
name: {
fontSize: 18,
fontWeight: '600',
color: '#2c3e50',
},
description: {
fontSize: 14,
color: '#7f8c8d',
marginTop: 4,
},
});Entrées de la documentation utilisées dans cette leçon
Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle valeur de justifyContent répartit les éléments uniformément avec un espacement égal entre eux ?
2. Que fait position : 'absolute' dans React Native ?
Tâches pratiques dans le jeu
- Tri vertical
Ordonne les valeurs de justifyContent du plus petit au plus grand espacement aux bords :
- Clique dans l'ordre
Clique sur les propriétés d'ombre dans le bon ordre (iOS) :
- Éditeur de code
Complète les styles pour une carte avec un effet d'ombre.