Material Design en React Native con Expo
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
- npx expo start
- Escanea el QR con Expo Go (Android o iOS).
- Revisa que los componentes Paper respetan el tema (colores, esquinas redondeadas, sombras).
- 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.
