Cours React Native · Module 2: Listes et styles
Responsivité et Dimensions
Dans cette leçon3
Les applications mobiles doivent fonctionner sur différentes tailles d'écran. Apprenons les techniques de responsivité !
API Dimensions
import { View, Text, StyleSheet, Dimensions, useWindowDimensions } from 'react-native';
// Dimensions statiques (au démarrage de l'app)
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');
export default function DimensionsExample() {
// Hook - mis à jour à la rotation de l'écran
const { width, height } = useWindowDimensions();
const isLandscape = width > height;
const isTablet = width >= 768;
return (
<View style={styles.container}>
<Text style={styles.text}>Largeur : {width}px</Text>
<Text style={styles.text}>Hauteur : {height}px</Text>
<Text style={styles.text}>
Orientation : {isLandscape ? 'Paysage' : 'Portrait'}
</Text>
<Text style={styles.text}>
Appareil : {isTablet ? 'Tablette' : 'Téléphone'}
</Text>
{/* Cartes responsives */}
<View style={[
styles.cardContainer,
isLandscape && styles.cardContainerLandscape
]}>
<View style={[styles.card, { width: width * 0.4 }]}>
<Text style={styles.cardText}>Carte 1</Text>
</View>
<View style={[styles.card, { width: width * 0.4 }]}>
<Text style={styles.cardText}>Carte 2</Text>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#1a5276',
},
text: {
fontSize: 16,
color: '#fff',
marginBottom: 8,
},
cardContainer: {
flexDirection: 'column',
gap: 16,
marginTop: 20,
},
cardContainerLandscape: {
flexDirection: 'row',
},
card: {
backgroundColor: '#2c3e50',
padding: 20,
borderRadius: 12,
minWidth: 150,
},
cardText: {
color: '#fff',
textAlign: 'center',
},
});Dimensions en pourcentage
import { View, StyleSheet } from 'react-native';
export default function PercentageExample() {
return (
<View style={styles.container}>
{/* Les pourcentages fonctionnent ! */}
<View style={styles.halfWidth} />
<View style={styles.thirdWidth} />
<View style={styles.fullWidth} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
gap: 10,
backgroundColor: '#1a5276',
},
halfWidth: {
width: '50%',
height: 60,
backgroundColor: '#e74c3c',
borderRadius: 8,
},
thirdWidth: {
width: '33.33%',
height: 60,
backgroundColor: '#2ecc71',
borderRadius: 8,
},
fullWidth: {
width: '100%',
height: 60,
backgroundColor: '#3498db',
borderRadius: 8,
},
});Grille responsive
import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';
export default function ResponsiveGrid() {
const { width } = useWindowDimensions();
// Calcule le nombre de colonnes selon la largeur
const numColumns = width >= 768 ? 4 : width >= 480 ? 3 : 2;
const itemWidth = (width - 40 - (numColumns - 1) * 10) / numColumns;
const items = Array.from({ length: 12 }, (_, i) => i + 1);
return (
<View style={styles.container}>
<Text style={styles.title}>Grille : {numColumns} colonnes</Text>
<View style={styles.grid}>
{items.map((item) => (
<View
key={item}
style={[styles.gridItem, { width: itemWidth, height: itemWidth }]}
>
<Text style={styles.itemText}>{item}</Text>
</View>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#1a5276',
},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#fff',
marginBottom: 16,
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
},
gridItem: {
backgroundColor: '#2c3e50',
borderRadius: 12,
justifyContent: 'center',
alignItems: 'center',
},
itemText: {
color: '#fff',
fontSize: 20,
fontWeight: 'bold',
},
});Code de cette leçon : App.tsx
import React from 'react';
import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';
export default function App() {
const { width } = useWindowDimensions();
// TODO : calcule le nombre de colonnes en fonction de la largeur de l'écran.
// Si width >= 768, définis numColumns à 4, sinon à 2.
// Exemple : const numColumns = width >= 768 ? 4 : 2;
const numColumns = 2;
const itemWidth = (width - 40 - (numColumns - 1) * 10) / numColumns;
const items = Array.from({ length: 8 }, (_, i) => i + 1);
return (
<View style={styles.container}>
<Text style={styles.title}>Trésors de l'Atlantide : {numColumns} colonnes</Text>
<View style={styles.grid}>
{items.map((item) => (
<View
key={item}
style={[styles.gridItem, { width: itemWidth, height: itemWidth }]}
>
<Text style={styles.itemText}>{item}</Text>
</View>
))}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#1a5276',
},
title: {
fontSize: 18,
fontWeight: 'bold',
color: '#fff',
marginBottom: 16,
},
grid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 10,
},
gridItem: {
backgroundColor: '#2c3e50',
borderRadius: 12,
justifyContent: 'center',
alignItems: 'center',
},
itemText: {
color: '#fff',
fontSize: 20,
fontWeight: 'bold',
},
});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. Comment obtient-on la largeur de l'écran avec l'API Dimensions ?
2. React Native prend-il en charge les valeurs en pourcentage dans les styles ?
Tâches pratiques dans le jeu
- Tri horizontal
Ordonne l'utilisation correcte du hook useWindowDimensions :
- Éditeur de code
Complète le code de la grille responsive.