TechLead
Lección 4 de 8

Estilos y Layouts

StyleSheet, layouts Flexbox, diseno responsivo y estilos especificos de plataforma

Estilos en React Native

React Native usa objetos JavaScript para los estilos en lugar de CSS. La API StyleSheet proporciona una forma optimizada de definir estilos.

StyleSheet.create

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

function MiComponente() {
  return (
    <View style={styles.contenedor}>
      <Text style={styles.titulo}>Hola Mundo</Text>
      <Text style={[styles.texto, styles.resaltado]}>
        Estilos combinados
      </Text>
    </View>
  );
}

const styles = StyleSheet.create({
  contenedor: {
    flex: 1,
    backgroundColor: '#fff',
    padding: 20,
  },
  titulo: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#333',
    marginBottom: 10,
  },
  texto: {
    fontSize: 16,
    color: '#666',
  },
  resaltado: {
    backgroundColor: '#ffeb3b',
    padding: 5,
  },
});

Flexbox en React Native

Flexbox funciona similar a CSS, pero con flexDirection: 'column' por defecto.

const styles = StyleSheet.create({
  // Contenedor de fila
  fila: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    alignItems: 'center',
  },

  // Contenedor de columna (por defecto)
  columna: {
    flexDirection: 'column',
    justifyContent: 'flex-start',
    alignItems: 'stretch',
  },

  // Centrado
  centrado: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },

  // Distribucion uniforme
  distribuido: {
    flexDirection: 'row',
    justifyContent: 'space-evenly',
  },
});

// Ejemplo de uso
function LayoutEjemplo() {
  return (
    <View style={styles.contenedor}>
      <View style={styles.fila}>
        <View style={styles.caja} />
        <View style={styles.caja} />
        <View style={styles.caja} />
      </View>
    </View>
  );
}

Estilos Condicionales y Dinamicos

function Boton({ primario, deshabilitado }) {
  return (
    <TouchableOpacity
      style={[
        styles.boton,
        primario && styles.botonPrimario,
        deshabilitado && styles.botonDeshabilitado,
      ]}
      disabled={deshabilitado}
    >
      <Text style={[
        styles.textoBoton,
        primario && styles.textoPrimario,
      ]}>
        Presionar
      </Text>
    </TouchableOpacity>
  );
}

const styles = StyleSheet.create({
  boton: {
    padding: 12,
    borderRadius: 8,
    backgroundColor: '#e0e0e0',
  },
  botonPrimario: {
    backgroundColor: '#007AFF',
  },
  botonDeshabilitado: {
    opacity: 0.5,
  },
  textoBoton: {
    color: '#333',
    textAlign: 'center',
  },
  textoPrimario: {
    color: '#fff',
  },
});

Dimensiones y Unidades

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

// Dimensiones estaticas
const { width, height } = Dimensions.get('window');

// Hook para dimensiones reactivas
function ComponenteResponsivo() {
  const { width, height } = useWindowDimensions();

  return (
    <View style={{
      width: width * 0.9, // 90% del ancho
      height: height * 0.5, // 50% del alto
    }}>
      <Text>Responsivo</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  // Valores absolutos (sin unidades)
  caja: {
    width: 100,  // 100 puntos
    height: 100, // 100 puntos
  },

  // Porcentajes
  contenedor: {
    width: '100%',
    height: '50%',
  },
});

Estilos Especificos de Plataforma

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

const styles = StyleSheet.create({
  contenedor: {
    paddingTop: Platform.OS === 'ios' ? 50 : 30,
    ...Platform.select({
      ios: {
        shadowColor: '#000',
        shadowOffset: { width: 0, height: 2 },
        shadowOpacity: 0.25,
        shadowRadius: 4,
      },
      android: {
        elevation: 5,
      },
    }),
  },
});

// O usando archivos separados:
// Boton.ios.js
// Boton.android.js
// import Boton from './Boton'; // Auto-selecciona

Propiedades de Estilo Comunes

  • flex, flexDirection, justifyContent, alignItems
  • width, height, minWidth, maxHeight
  • margin, padding (marginTop, paddingHorizontal, etc.)
  • backgroundColor, borderColor, borderWidth, borderRadius
  • fontSize, fontWeight, color, textAlign
  • position ('relative' por defecto, 'absolute')