Material Design en React Native con Expo

in #desaappmovil7 days ago (edited)

_cuatro.png

Objetivo: Crear una pequeña app con Expo que use componentes de Material Design (React Native Paper), un tema personalizado, navegación básica y ejemplos de FAB, Card y Appbar.

Requisitos previos

  • Node.js y npm / yarn instalados.
  • Expo CLI (si no lo tienes: npm install -g expo-cli o usar npx expo sin global).
  • Conocimientos básicos de React/React Native (JSX, componentes).
  • La app Expo Go en tu móvil.

1) Crear el proyecto Expo

Abre la terminal y ejecuta:

    npx expo init md-react-native-practice
    # elige "blank (TypeScript)" o "blank (JavaScript)" según prefieras; 
    # en este ejemplo se usa JavaScript
    cd md-react-native-practice

Inicia el proyecto para verificar que corre:

    npx expo start

Escanea con Expo Go o abre el emulador.

2) Instalar dependencias de Material Design

Vamos a usar React Native Paper, una librería que implementa Material Design para React Native y funciona muy bien con Expo.

Instala:

    npm install react-native-paper
    # opcionalmente instalar iconos
    npm install react-native-vector-icons
    # si usas expo-managed workflow, vector icons ya vienen incluidas con expo, pero instalar no hace daño

Si usas navegación (recomendado para un ejemplo con Bottom Navigation):

    npm install @react-navigation/native @react-navigation/native-stack
    npm install react-native-screens react-native-safe-area-context
    # y para bottom tabs (opcional)
    npm install @react-navigation/bottom-tabs

Con Expo, react-native-vector-icons está disponible a través de @expo/vector-icons, así que no siempre hace falta instalarlo por separado.

3) Estructura sugerida de archivos

En la carpeta del proyecto, crea:

    /components
          AppHeader.js
          HomeScreen.js
          DetailsScreen.js
   /App.js

4) Configurar el provider de React Native Paper y tema (App.js)

Crea un tema basado en Material (puedes adaptar colores). Puedes guiarte de este código en App.js:

// App.js
import * as React from 'react';
import { Provider as PaperProvider, DefaultTheme, DarkTheme } from 'react-native-paper';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import HomeScreen from './components/HomeScreen';
import DetailsScreen from './components/DetailsScreen';

const Stack = createNativeStackNavigator();

// Personaliza el tema Material
const theme = {
  ...DefaultTheme,
  colors: {
    ...DefaultTheme.colors,
    primary: '#0D47A1',      // azul principal
    accent: '#FF6F00',       // color de acento (FAB, highlights)
    background: '#F5F7FA',
    surface: '#FFFFFF',
    text: '#1A1A1A',
  },
  roundness: 8,
};

export default function App() {
  return (
    <PaperProvider theme={theme}>
      <NavigationContainer>
        <Stack.Navigator initialRouteName="Home" screenOptions={{ headerShown: false }}>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Details" component={DetailsScreen} />
        </Stack.Navigator>
      </NavigationContainer>
    </PaperProvider>
  );
}

Qué hace: PaperProvider aplica el tema de Material Design en toda la app. DefaultTheme es la base; lo personalizamos.

5) Crear la pantalla principal con componentes Material (HomeScreen.js)

Crea un HomeScreen que muestre Appbar, Card, lista y un FAB:

// components/HomeScreen.js
import React from 'react';
import { View, ScrollView, StyleSheet } from 'react-native';
import { Appbar, Card, Title, Paragraph, FAB, Button } from 'react-native-paper';
import { useNavigation } from '@react-navigation/native';

export default function HomeScreen() {
  const navigation = useNavigation();

  return (
    <View style={styles.container}>
      <Appbar.Header>
        <Appbar.Content title="Mi Agenda" subtitle="Ejemplo con Material Design" />
        <Appbar.Action icon="magnify" onPress={() => {}} />
      </Appbar.Header>

      <ScrollView contentContainerStyle={styles.content}>
        <Card style={styles.card} onPress={() => navigation.navigate('Details')}>
          <Card.Content>
            <Title>Organiza tu día</Title>
            <Paragraph>Una pequeña tarjeta con información y llamada a la acción.</Paragraph>
          </Card.Content>
          <Card.Actions>
            <Button onPress={() => navigation.navigate('Details')}>Ver</Button>
          </Card.Actions>
        </Card>

        <Card style={styles.card}>
          <Card.Content>
            <Title>Recordatorio</Title>
            <Paragraph>Configura alertas y notificaciones para tus tareas.</Paragraph>
          </Card.Content>
        </Card>
      </ScrollView>

      <FAB
        style={styles.fab}
        icon="plus"
        onPress={() => console.log('Crear nuevo')}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  content: { padding: 16 },
  card: { marginBottom: 12 },
  fab: {
    position: 'absolute',
    right: 16,
    bottom: 24,
  },
});

Puntos clave: Appbar.Header para la barra superior, Card para contenido, FAB (Floating Action Button) para la acción principal. Todos son componentes Material.

6) Crear pantalla de detalle (DetailsScreen.js)

// components/DetailsScreen.js
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { Appbar, Text } from 'react-native-paper';
import { useNavigation } from '@react-navigation/native';

export default function DetailsScreen() {
  const navigation = useNavigation();
  return (
    <View style={styles.container}>
      <Appbar.Header>
        <Appbar.BackAction onPress={() => navigation.goBack()} />
        <Appbar.Content title="Detalle" />
      </Appbar.Header>

      <View style={styles.content}>
        <Text variant="headlineSmall">Detalles de la tarea</Text>
        <Text>Descripción, fechas y opciones para editar.</Text>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1 },
  content: { padding: 16 },
});

7) Personalización avanzada: tema dinámico (opcional)

Para permitir cambiar entre tema claro y oscuro, podrías extender App.js:


// dentro de App.js
import { useEffect, useState } from 'react';
import { Appearance } from 'react-native';

export default function App() {
  const colorScheme = Appearance.getColorScheme();
  const [isDark, setIsDark] = useState(colorScheme === 'dark');

  useEffect(() => {
    const sub = Appearance.addChangeListener(({ colorScheme }) => {
      setIsDark(colorScheme === 'dark');
    });
    return () => sub.remove();
  }, []);

  const appliedTheme = isDark ? DarkTheme : theme;

  return (
    <PaperProvider theme={appliedTheme}>
      ...
    </PaperProvider>
  );
}

8) Accesibilidad y buenas prácticas (breve checklist)

  • Contraste: verifica contraste de texto contra fondo (WCAG).
  • Tamaño de touch targets: botones con área mínima ~48x48 dp.
  • Lectores de pantalla: añade accessibilityLabel en botones y elementos interactivos.
  • Soporte de tamaños de fuente: no fijar tamaños rígidos; permitir escalado.
  • Pruebas en dispositivos reales (Android y iOS).
    Ejemplo de accessibilityLabel:
<FAB
  style={styles.fab}
  icon="plus"
  accessibilityLabel="Crear tarea nueva"
  onPress={() => console.log('Crear nuevo')}
/>

9) Probar en dispositivo / Expo Go

  1. npx expo start
  2. Escanea el QR con Expo Go (Android o iOS).
  3. Revisa que los componentes Paper respetan el tema (colores, esquinas redondeadas, sombras).
  4. Prueba rotación, accesibilidad y el comportamiento de FAB.

10) Extensiones y siguientes pasos (ideas de ampliación)

  • Integrar React Native Paper Bottom Navigation o react-navigation bottom tabs para ver patrones de navegación Material.
  • Usar la librería react-native-animated o react-native-reanimated para microinteracciones complejas.
  • Exportar un kit de diseño en Figma usando los Material Design Kits para prototipado previo.
  • Implementar componentes personalizados con Surface y elevation para controlar jerarquía.

[!TIP]
Tips finales y recomendaciones prácticas:
Empieza por el prototipo en Figma usando Material Kit: te ayudará a definir jerarquía antes de codificar.
Apóyate en componentes estándar: aceleran desarrollo y garantizan consistencia.
No abuses de animaciones: úsalas para guiar, no para distraer.
Revisa guidelines de Material Design: en material.io cuando dudes sobre elevación, espaciado o comportamiento de componentes.

Repositorio de Material Design en GitHub