Introduction: Space FM Player

Welcome to the second lesson of the Core Components in React Native course! In our previous lesson, you built a Space Docking Notification Card, where you learned to use core components like View, Text, Image, and TouchableOpacity to create a practical notification UI. Now, we’ll take your skills further by building a space FM player — a music player interface for your interstellar journey. This lesson will focus on combining React Native’s core components to create a clean, functional, and visually appealing player. By the end, you’ll see how these building blocks come together to form a more complex, real-world interface.

Key Components for the Player

To build the space FM player, we’ll use several essential React Native components. Some, like View, Text, and TouchableOpacity, will be familiar from the previous lesson (consider this a quick review). Others, such as ScrollView and StatusBar, will be introduced here for the first time.

Let’s start with the basic structure. The View component is used to group and arrange other components, while Text displays the lyrics and track information. To handle long lyrics that might not fit on the screen, we’ll use ScrollView, which allows users to scroll through content vertically. For the player controls, we’ll use TouchableOpacity to create custom, tappable buttons. The Image component is used for icons and artwork.

Here’s a minimal example showing how these components fit together:

import React from "react";
import { View, Text, ScrollView, TouchableOpacity } from "react-native";

const SpaceFMPlayer = () => {
  return (
    <View>
      <ScrollView>
        <Text>Lyrics go here...</Text>
      </ScrollView>
      <View>
        <Text>Track Title</Text>
        <Text>Artist Name</Text>
      </View>
      <View>
        <TouchableOpacity>
          <Text>Play</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

In this example, the ScrollView wraps the lyrics, the track info is grouped in a View, and the controls are represented by a TouchableOpacity button. This structure forms the foundation of our player.

Using StatusBar and SafeAreaView

To create a polished, immersive experience, it’s important to control the appearance of the device’s status bar and ensure your content is displayed within the safe area of the device (avoiding notches and system UI). The StatusBar component lets you set the style of the status bar (for example, light text on a dark background), and SafeAreaView ensures your UI doesn’t overlap with device edges.

Here’s how you can set up your app to use these components, along with the player:

import React from "react";
import { StatusBar, SafeAreaView } from "react-native";
import { useKeepAwake } from 'expo-keep-awake';
import SpaceFMPlayer from './SpaceFMPlayer';

const App = () => {
  useKeepAwake();
  
  return (
    <SafeAreaView style={{flex: 1, backgroundColor: "#101523"}}>
      <StatusBar barStyle='light-content'/>
      <SpaceFMPlayer />
    </SafeAreaView>
  );
};

export default App;
  • StatusBar with barStyle='light-content' ensures the status bar text/icons are light, matching the dark background.
  • SafeAreaView wraps the player and sets the background color, keeping content within safe device boundaries.
  • useKeepAwake (from expo-keep-awake) is optional, but it prevents the screen from sleeping while the player is open.
Solving Common UI Challenges

Building a music player interface comes with a few common challenges. One is handling long blocks of text, such as song lyrics. If you simply use a Text component, the content might overflow the screen. By wrapping the lyrics in a ScrollView, you allow users to scroll through the text smoothly.

Another challenge is organizing the layout so that the lyrics, track information, and controls are easy to find and use. Using nested View components and applying styles helps keep everything clear and visually appealing. For example, you might want the lyrics to take up most of the screen, with the track info and controls anchored at the bottom.

Here’s a snippet that demonstrates how to use ScrollView for lyrics and arrange the controls:

<ScrollView style={{ flex: 1 }}>
  <Text>
    (Verse 1){"\n"}
    Zoomin’ through the galaxy, tail all aglow,{"\n"}
    Cosmo the Corgi’s got places to go!
  </Text>
</ScrollView>
<View style={{ flexDirection: "row", justifyContent: "center" }}>
  <TouchableOpacity>
    <Text>Play</Text>
  </TouchableOpacity>
</View>

The ScrollView ensures the lyrics are scrollable, and the controls are placed in a horizontal row at the bottom. This approach keeps the interface organized and user-friendly.

Step-by-Step Example: Building the Space FM Player

Let’s put everything together and walk through a more complete example. We’ll use styles to polish the look, nest Text components to highlight different lyric sections, and add custom player controls.

import React from "react";
import { View, Text, StyleSheet, TouchableOpacity, ScrollView } from "react-native";
import { Ionicons } from "@expo/vector-icons";

const SpaceFMPlayer = () => {
  return (
    <View style={styles.container}>
      <ScrollView style={styles.lyricsContainer}>
        <Text style={styles.lyrics}>
          <Text style={styles.pastLyrics}>
            (Verse 1){"\n"}
            Zoomin’ through the galaxy, tail all aglow,{"\n"}
            Cosmo the Corgi’s got places to go!{"\n"}
            Rocket pack strapped, ears in the breeze,{"\n"}
            Bouncin’ on asteroids with zero-Gs!{"\n\n"}
          </Text>
          <Text style={styles.futureLyrics}>
            (Verse 2){"\n"}
            Dodgin’ black holes, ridin’ a star,{"\n"}
            Snackin’ on moon cheese from way up afar!{"\n"}
            Martian pups barkin’, they wanna play,{"\n"}
            Cosmo just zooms with a “Yip! Hooray!”{"\n\n"}
          </Text>
        </Text>
      </ScrollView>

      <View style={styles.trackInfo}>
        <Text style={styles.trackTitle}>Cosmo the Space Corgi</Text>
        <Text style={styles.artistName}>Cosmic Pawsy</Text>
      </View>

      <View style={styles.controls}>
        <TouchableOpacity style={styles.button}>
          <Ionicons name="play-skip-back" size={32} color="#fff" />
        </TouchableOpacity>
        <TouchableOpacity style={[styles.button, styles.playButton]}>
          <Ionicons name="play" size={40} color="#fff" />
        </TouchableOpacity>
        <TouchableOpacity style={styles.button}>
          <Ionicons name="play-skip-forward" size={32} color="#fff" />
        </TouchableOpacity>
      </View>
    </View>
  );
};

export default SpaceFMPlayer;
import { StyleSheet } from "react-native";

const styles = StyleSheet.create({
  // Main container: fills the screen, centers content, sets background color
  container: {
    flex: 1,
    justifyContent: "space-between",
    alignItems: "center",
    backgroundColor: "#101523",
  },
  // Scrollable lyrics area: takes up available space, full width
  lyricsContainer: {
    flex: 1,
    width: "100%",
  },
  // Main lyrics text: centered, large font, extra padding at bottom
  lyrics: {
    textAlign: "center",
    fontSize: 32,
    paddingBottom: 50,
  },
  // Past lyrics: bold and white for emphasis
  pastLyrics: {
    fontWeight: "bold",
    color: "#fff",
  },
  // Future lyrics: lighter color to indicate upcoming lines
  futureLyrics: {
    color: "#aaa",
  },
  // Track info section: full width, left-aligned, with border and padding
  trackInfo: {
    width: "100%",
    alignItems: "flex-start",
    marginBottom: 20,
    borderTopColor: "#eee",
    borderTopWidth: 2,
    padding: 10,
  },
  // Track title: larger, bold, white text
  trackTitle: {
    fontSize: 18,
    fontWeight: "bold",
    color: "#fff",
  },
  // Artist name: smaller, lighter color
  artistName: {
    fontSize: 14,
    color: "#aaa",
  },
  // Controls row: horizontal layout, centered, with spacing
  controls: {
    flexDirection: "row",
    alignItems: "center",
    gap: 40,
    marginBottom: 20,
  },
  // Control button: circular, centered content
  button: {
    width: 48,
    height: 48,
    justifyContent: "center",
    alignItems: "center",
    borderRadius: 999,
    padding: 10,
  },
  // Play button: larger, with background color
  playButton: {
    width: 64,
    height: 64,
    backgroundColor: "#121828",
    padding: 16,
    borderRadius: 999,
  },
});

In this example, the lyrics are split into two sections: past and future, each styled differently for emphasis. The ScrollView allows the lyrics to be scrolled if they’re too long for the screen. The track information is displayed below the lyrics, and the player controls are arranged in a row at the bottom, using icons for a modern look. The styles ensure everything is spaced and colored for readability and visual appeal.

Summary and What’s Next

In this lesson, you learned how to combine React Native’s core components to build a functional and attractive music player interface. We reviewed familiar components like View, Text, and TouchableOpacity, and introduced new ones such as ScrollView and StatusBar. You saw how to solve common UI challenges, like handling long lyrics and organizing controls, and you followed a step-by-step example to assemble the space FM player.

This lesson builds directly on your experience with the notification card, showing how the same building blocks can be used in new and creative ways. Up next, you’ll get hands-on practice by building and customizing your own space FM player. This will help reinforce what you’ve learned and prepare you for even more advanced layouts in future lessons. Let’s get started!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal