Cours React Native · Module 2: Listes et styles

Responsivité et Dimensions

3 min de lecture ·
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. 1. Comment obtient-on la largeur de l'écran avec l'API Dimensions ?

  2. 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.

Articles utiles