Kurs React Native · Moduł 2: Listy i style

Responsywność i Dimensions

3 min czytania ·
W tej lekcji3

Aplikacje mobilne muszą działać na różnych rozmiarach ekranów. Poznajmy techniki responsywności!

Dimensions API

import { View, Text, StyleSheet, Dimensions, useWindowDimensions } from 'react-native';

// Statyczne wymiary (przy starcie aplikacji)
const { width: SCREEN_WIDTH, height: SCREEN_HEIGHT } = Dimensions.get('window');

export default function DimensionsExample() {
  // Hook - aktualizuje się przy obrocie ekranu
  const { width, height } = useWindowDimensions();

  const isLandscape = width > height;
  const isTablet = width >= 768;

  return (
    <View style={styles.container}>
      <Text style={styles.text}>Szerokość: {width}px</Text>
      <Text style={styles.text}>Wysokość: {height}px</Text>
      <Text style={styles.text}>
        Orientacja: {isLandscape ? 'Pozioma' : 'Pionowa'}
      </Text>
      <Text style={styles.text}>
        Urządzenie: {isTablet ? 'Tablet' : 'Telefon'}
      </Text>

      {/* Responsywne karty */}
      <View style={[
        styles.cardContainer,
        isLandscape && styles.cardContainerLandscape
      ]}>
        <View style={[styles.card, { width: width * 0.4 }]}>
          <Text style={styles.cardText}>Karta 1</Text>
        </View>
        <View style={[styles.card, { width: width * 0.4 }]}>
          <Text style={styles.cardText}>Karta 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',
  },
});

Procentowe wymiary

import { View, StyleSheet } from 'react-native';

export default function PercentageExample() {
  return (
    <View style={styles.container}>
      {/* Procenty działają! */}
      <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,
  },
});

Grid responsywny

import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';

export default function ResponsiveGrid() {
  const { width } = useWindowDimensions();

  // Oblicz liczbę kolumn na podstawie szerokości
  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}>Grid: {numColumns} kolumny</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',
  },
});
Kod do tej lekcji: App.tsx
import React from 'react';
import { View, Text, StyleSheet, useWindowDimensions } from 'react-native';

export default function App() {
  const { width } = useWindowDimensions();

  // TODO: oblicz liczbę kolumn na podstawie szerokości ekranu.
  //   Jeśli width >= 768, ustaw numColumns na 4, w przeciwnym razie na 2.
  //   Przykład: 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}>Skarby Atlantydy: {numColumns} kolumny</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',
  },
});

Hasła z dokumentacji w tej lekcji

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Jak pobrać szerokość ekranu za pomocą Dimensions API?

  2. 2. Czy React Native obsługuje wartości procentowe w stylach?

Zadania praktyczne w grze

  • Układanie w poziomie

    Ułóż poprawne użycie hooka useWindowDimensions:

  • Edytor kodu

    Uzupełnij kod responsywnej siatki.

Przydatne artykuły