10.1. Componente StatusBar.

 

Tutorial: Componente StatusBar en React Native

📱 Parte 10: Componente StatusBar - Control de la Barra de Estado

🎯 Objetivo:

Aprender a usar el componente StatusBar para controlar la apariencia de la barra de estado en dispositivos iOS y Android, mejorando la experiencia de usuario y la estética de tu aplicación.


📸 Entendiendo StatusBar desde la Imagen

Analizando el código de la imagen:

javascript

const App = () => {

  return (

    <>

      <StatusBar barStyle="light-content" />  {/* ¡ESTA ES LA STATUSBAR! */}

      <SafeAreaView forceInset={{top: 'never'}}>

        <ScrollView contentInsetAdjustmentBehavior="automatic">

          {/* Resto del contenido... */}

        </ScrollView>

      </SafeAreaView>

    </>

  );

};

Resultado visual:

text

┌─────────────────────────────────┐

│ ⏰ 📶 🔋  (TEXTO BLANCO)         │ ← ¡STATUSBAR CON 'light-content'!

│                                 │

│        CONTENIDO DE LA APP      │

│                                 │

└─────────────────────────────────┘


📱 Paso 1: ¿Qué es StatusBar?

La StatusBar es la barra superior del sistema que muestra:

text

┌─────────────────────────────────┐

│ 📶  5:28 PM  🔋 84%             │ ← ¡ESTA ES LA STATUSBAR!

│                                 │

│        TU APLICACIÓN            │

│                                 │

└─────────────────────────────────┘

Elementos que muestra:

  • ⏰ Hora actual del sistema

  • 📶 Indicador de señal celular

  • 📡 Iconos de conexión (Wi-Fi, datos)

  • 🔋 Nivel de batería

  • 🔔 Notificaciones pendientes


🚀 Paso 2: Configuración Básica de StatusBar

2.1 Importación

javascript

import React from 'react';

import { StatusBar } from 'react-native'; // ¡Importar siempre!

2.2 Uso Más Simple

javascript

const AppBasica = () => {

  return (

    <>

      <StatusBar />

      {/* Resto de tu aplicación */}

    </>

  );

};


🎨 Paso 3: barStyle - Control del Color del Texto

3.1 Demostración Visual de barStyle

javascript

import React, { useState } from 'react';

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


const BarStyleDemo = () => {

  const [barStyle, setBarStyle] = useState('dark-content');


  const toggleBarStyle = () => {

    setBarStyle(prev => 

      prev === 'dark-content' ? 'light-content' : 'dark-content'

    );

  };


  return (

    <View style={[

      styles.container,

      barStyle === 'dark-content' ? styles.lightBackground : styles.darkBackground

    ]}>

      {/* StatusBar dinámica */}

      <StatusBar barStyle={barStyle} />

      

      <Text style={styles.title}>

        StatusBar: {barStyle === 'dark-content' ? 'Texto Oscuro' : 'Texto Blanco'}

      </Text>

      

      <Text style={styles.description}>

        {barStyle === 'dark-content' 

          ? '📱 Hora, señal y batería en NEGRO' 

          : '📱 Hora, señal y batería en BLANCO'}

      </Text>

      

      <View style={styles.statusBarSimulator}>

        <Text style={[

          styles.statusBarText,

          barStyle === 'dark-content' ? styles.darkText : styles.lightText

        ]}>

          5:28 PM  📶  🔋 84%

        </Text>

      </View>

      

      <Button 

        title={`Cambiar a ${barStyle === 'dark-content' ? 'Blanco' : 'Negro'}`}

        onPress={toggleBarStyle}

      />

    </View>

  );

};


const styles = StyleSheet.create({

  container: {

    flex: 1,

    justifyContent: 'center',

    alignItems: 'center',

    padding: 20,

  },

  lightBackground: {

    backgroundColor: '#FFFFFF',

  },

  darkBackground: {

    backgroundColor: '#1E1E1E',

  },

  title: {

    fontSize: 24,

    fontWeight: 'bold',

    marginBottom: 20,

  },

  description: {

    fontSize: 16,

    textAlign: 'center',

    marginBottom: 30,

  },

  statusBarSimulator: {

    width: '100%',

    height: 40,

    backgroundColor: barStyle === 'dark-content' ? '#F2F2F7' : '#000000',

    justifyContent: 'center',

    alignItems: 'center',

    marginBottom: 40,

    borderRadius: 8,

  },

  statusBarText: {

    fontSize: 14,

    fontWeight: '500',

  },

  darkText: {

    color: '#000000',

  },

  lightText: {

    color: '#FFFFFF',

  },

});

3.2 Visualización de las Diferencias

text

DARK-CONTENT:                            LIGHT-CONTENT:

┌─────────────────────────────────┐     ┌─────────────────────────────────┐

│ ⏰ 📶 🔋  (TEXTO NEGRO)          │     │ ⏰ 📶 🔋  (TEXTO BLANCO)         │

│                                 │     │                                 │

│ FONDO CLARO                    │     │ FONDO OSCURO                    │

│ Mejor visibilidad              │     │ Mejor contraste                 │

└─────────────────────────────────┘     └─────────────────────────────────┘


🔧 Paso 4: Opciones de barStyle

4.1 Los 3 Valores Posibles

javascript

const App = () => {

  return (

    <>

      {/* Opción 1: Texto blanco (recomendado para fondos oscuros) */}

      <StatusBar barStyle="light-content" />

      

      {/* Opción 2: Texto negro (recomendado para fondos claros) */}

      <StatusBar barStyle="dark-content" />

      

      {/* Opción 3: Por defecto del sistema */}

      <StatusBar barStyle="default" />

    </>

  );

};

4.2 Ejemplo Práctico: Aplicación con Tema Oscuro/Claro

javascript

import React, { useState } from 'react';

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


const ThemeSwitcher = () => {

  const [isDarkMode, setIsDarkMode] = useState(false);


  return (

    <>

      {/* StatusBar que cambia con el tema */}

      <StatusBar 

        barStyle={isDarkMode ? "light-content" : "dark-content"}

        backgroundColor={isDarkMode ? "#1E1E1E" : "#FFFFFF"}

      />

      

      <View style={[

        styles.container,

        isDarkMode ? styles.darkContainer : styles.lightContainer

      ]}>

        <Text style={[

          styles.title,

          isDarkMode ? styles.darkText : styles.lightText

        ]}>

          {isDarkMode ? '🌙 Modo Oscuro' : '☀️ Modo Claro'}

        </Text>

        

        <View style={styles.switchContainer}>

          <Text style={isDarkMode ? styles.darkText : styles.lightText}>

            Modo Oscuro

          </Text>

          <Switch

            value={isDarkMode}

            onValueChange={setIsDarkMode}

            trackColor={{ false: "#767577", true: "#81b0ff" }}

            thumbColor={isDarkMode ? "#f5dd4b" : "#f4f3f4"}

          />

        </View>

        

        <View style={styles.statusBarPreview}>

          <Text style={[

            styles.statusBarText,

            isDarkMode ? styles.lightText : styles.darkText

          ]}>

            5:28 PM  📶  🔋 {isDarkMode ? '84%' : '64%'}

          </Text>

        </View>

        

        <Text style={[

          styles.explanation,

          isDarkMode ? styles.darkText : styles.lightText

        ]}>

          {isDarkMode 

            ? '✅ StatusBar con texto BLANCO sobre fondo OSCURO' 

            : '✅ StatusBar con texto NEGRO sobre fondo CLARO'}

        </Text>

      </View>

    </>

  );

};


const styles = StyleSheet.create({

  container: {

    flex: 1,

    justifyContent: 'center',

    alignItems: 'center',

    padding: 20,

  },

  lightContainer: {

    backgroundColor: '#FFFFFF',

  },

  darkContainer: {

    backgroundColor: '#1E1E1E',

  },

  title: {

    fontSize: 28,

    fontWeight: 'bold',

    marginBottom: 30,

  },

  lightText: {

    color: '#000000',

  },

  darkText: {

    color: '#FFFFFF',

  },

  switchContainer: {

    flexDirection: 'row',

    alignItems: 'center',

    gap: 15,

    marginBottom: 40,

  },

  statusBarPreview: {

    width: '90%',

    height: 44,

    backgroundColor: isDarkMode ? '#000000' : '#F2F2F7',

    justifyContent: 'center',

    alignItems: 'center',

    borderRadius: 10,

    marginBottom: 30,

  },

  statusBarText: {

    fontSize: 15,

    fontWeight: '600',

  },

  explanation: {

    fontSize: 16,

    textAlign: 'center',

    marginTop: 20,

    paddingHorizontal: 20,

  },

});


📱 Paso 5: Diferencias entre iOS y Android

5.1 Configuración Específica por Plataforma

javascript

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


const App = () => {

  return (

    <>

      <StatusBar 

        // iOS y Android soportan barStyle

        barStyle={Platform.OS === 'ios' ? 'dark-content' : 'light-content'}

        

        // backgroundColor solo funciona en Android

        backgroundColor={Platform.OS === 'android' ? '#6200ee' : 'transparent'}

        

        // translucent solo funciona en Android

        translucent={Platform.OS === 'android'}

      />

      {/* Resto de la app */}

    </>

  );

};

5.2 Tabla de Compatibilidad

Propiedad

iOS

Android

barStyle

backgroundColor

translucent

hidden

animated

networkActivityIndicatorVisible


🎯 Paso 6: Ejemplos Prácticos Comunes

6.1 Pantalla con Imagen de Fondo

javascript

const ImageBackgroundScreen = () => {

  return (

    <>

      {/* StatusBar con texto blanco para contrastar con imagen */}

      <StatusBar 

        barStyle="light-content"

        translucent={true}

        backgroundColor="transparent"

      />

      

      <ImageBackground 

        source={require('./background.jpg')}

        style={styles.background}

      >

        <SafeAreaView style={styles.container}>

          <Text style={styles.title}>Bienvenido</Text>

          {/* Resto del contenido */}

        </SafeAreaView>

      </ImageBackground>

    </>

  );

};

6.2 Pantalla con Header de Color

javascript

const ColoredHeaderScreen = () => {

  return (

    <View style={styles.container}>

      {/* StatusBar que combina con el header */}

      <StatusBar 

        barStyle="light-content"

        backgroundColor="#1976d2" // Mismo color que el header

      />

      

      {/* Header */}

      <View style={styles.header}>

        <Text style={styles.headerTitle}>Mi App</Text>

      </View>

      

      {/* Contenido */}

      <ScrollView style={styles.content}>

        <Text>Contenido principal aquí</Text>

      </ScrollView>

    </View>

  );

};

6.3 StatusBar Dinámica (Cambia con Scroll)

javascript

import React, { useState } from 'react';

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


const DynamicStatusBar = () => {

  const [isScrolled, setIsScrolled] = useState(false);


  const handleScroll = (event) => {

    const offsetY = event.nativeEvent.contentOffset.y;

    setIsScrolled(offsetY > 100);

  };


  return (

    <View style={{ flex: 1 }}>

      {/* StatusBar que cambia al hacer scroll */}

      <StatusBar 

        barStyle={isScrolled ? 'dark-content' : 'light-content'}

        backgroundColor={isScrolled ? 'white' : 'transparent'}

        animated={true}

      />

      

      <ScrollView 

        onScroll={handleScroll}

        scrollEventThrottle={16}

        style={{ flex: 1 }}

      >

        <View style={{ height: 300, backgroundColor: '#6200ee' }}>

          <Text style={{ color: 'white', padding: 20 }}>

            Desplázate para cambiar la StatusBar

          </Text>

        </View>

        

        {/* Contenido largo */}

        {Array.from({ length: 50 }).map((_, index) => (

          <View key={index} style={{ padding: 20 }}>

            <Text>Elemento {index + 1}</Text>

          </View>

        ))}

      </ScrollView>

    </View>

  );

};


⚡ Paso 7: API de StatusBar (Métodos Estáticos)

7.1 Cambiar StatusBar Dinámicamente

javascript

import { StatusBar } from 'react-native';


// Ejemplo: Cambiar en diferentes pantallas

const ProfileScreen = () => {

  React.useEffect(() => {

    // Al entrar a esta pantalla

    StatusBar.setBarStyle('dark-content', true); // animated

    

    // Al salir de esta pantalla

    return () => {

      StatusBar.setBarStyle('light-content', true);

    };

  }, []);


  return (

    <View style={{ flex: 1 }}>

      <Text>Perfil del Usuario</Text>

    </View>

  );

};

7.2 Ocultar/Mostrar StatusBar

javascript

// Ocultar con animación

StatusBar.setHidden(true, 'fade'); // 'none', 'fade', 'slide'


// Mostrar con animación

StatusBar.setHidden(false, 'slide');


// Cambiar color de fondo (Android)

StatusBar.setBackgroundColor('#000000', true);


🔧 Paso 8: Combinación con SafeAreaView

8.1 Configuración Óptima para iOS

javascript

const AppiOS = () => {

  return (

    <>

      <StatusBar barStyle="dark-content" />

      <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>

        {/* Contenido que respeta el notch */}

        <Text>Contenido seguro</Text>

      </SafeAreaView>

    </>

  );

};

8.2 Configuración para Android

javascript

const AppAndroid = () => {

  return (

    <>

      <StatusBar 

        barStyle="light-content"

        backgroundColor="#6200ee"

        translucent={true}

      />

      

      {/* Espacio para la StatusBar */}

      <View style={{ 

        paddingTop: StatusBar.currentHeight,

        flex: 1,

        backgroundColor: '#fff'

      }}>

        <Text>Contenido</Text>

      </View>

    </>

  );

};


⚠️ Paso 9: Problemas Comunes y Soluciones

❌ Problema: StatusBar no cambia en iOS

javascript

// SOLUCIÓN: Asegurar que StatusBar esté en la raíz

<>

  <StatusBar barStyle="dark-content" />

  <SafeAreaView style={{ flex: 1 }}>

    {/* Contenido */}

  </SafeAreaView>

</>

❌ Problema: Contenido detrás de StatusBar en Android

javascript

// SOLUCIÓN: Usar translucent y padding

<>

  <StatusBar translucent backgroundColor="transparent" />

  <View style={{ 

    flex: 1,

    paddingTop: Platform.OS === 'android' ? StatusBar.currentHeight : 0

  }}>

    <Text>Contenido</Text>

  </View>

</>

❌ Problema: Color no aplica en iOS

javascript

// iOS no soporta backgroundColor directamente

// SOLUCIÓN: Usar un View con el color

<>

  <StatusBar barStyle="light-content" />

  <View style={{ 

    height: Platform.OS === 'ios' ? 44 : StatusBar.currentHeight,

    backgroundColor: 'tu-color'

  }} />

</>


📋 Paso 10: Mejores Prácticas

10.1 Checklist para StatusBar Perfecta

  • Testear en iOS y Android por separado

  • Usar animated={true} para transiciones suaves

  • Combinar con SafeAreaView en iOS

  • Considerar el contraste con el fondo

  • Usar valores dinámicos para temas oscuro/claro

10.2 Configuración Recomendada

javascript

const App = () => {

  return (

    <>

      <StatusBar 

        barStyle="dark-content"

        backgroundColor="transparent"

        translucent={true}

        animated={true}

      />

      <SafeAreaView style={{ flex: 1, backgroundColor: '#fff' }}>

        {/* Tu aplicación */}

      </SafeAreaView>

    </>

  );

};


🎯 Ejercicio Práctico

Crea una aplicación con:

  1. ✅ Pantalla de inicio con StatusBar clara sobre imagen

  2. ✅ Pantalla de configuración con StatusBar oscura

  3. ✅ Botón para alternar entre modos claro/oscuro

  4. ✅ Header que cambia color junto con la StatusBar

Bonus: Implementa detección automática del tema del sistema.


📊 Resumen de Propiedades

Propiedad

Valores

Descripción

barStyle

'default', 'light-content', 'dark-content'

Color del texto

backgroundColor

Color hexadecimal

Fondo (solo Android)

translucent

true/false

Transparente (solo Android)

hidden

true/false

Mostrar/ocultar

animated

true/false

Transiciones animadas

networkActivityIndicatorVisible

true/false

Indicador red (solo iOS)


🎬 Próximo Tutorial

En el siguiente video aprenderemos:

  • Componente SafeAreaView para contenido seguro

  • Manejo de notches y áreas no seguras

  • Compatibilidad con diferentes dispositivos

  • Mejores prácticas para diseño responsivo


✅ ¡Ahora controlas completamente la StatusBar! Recuerda que una StatusBar bien configurada mejora significativamente la experiencia de usuario y da un aspecto profesional a tu aplicación


Comentarios

Entradas más populares de este blog

18. Visualizar nuestros componentes limpios con StyleSheet

15. Componente Image

Tema: 23. Justify Content en Flexbox para Column (Columna) en React Nativ