Loading..

React Native 앱에 Splash 스크린 추가

2019.07.02 20:47

React Native 앱에 Splash 스크린 추가

개요

많은 어플리케이션에서는 앱이 실행될 때 Splash 스크린을 띄워, 미리 데이터를 가져오거나 백그라운드 작업을 처리한 뒤 앱을 실행하는 경우가 많습니다. 오늘은 react-native-splash-screen 라이브러리를 통해 Splash 스크린을 구현하겠습니다.

개발 환경

  • React 버전 16.8.3, React Native 버전 0.59.9 버전을 사용하고 있습니다.
  • 패키지 매니저로 Yarn을 사용하고 있습니다.

라이브러리 설치

우선 react-native-splash-screen을 설치하겠습니다.

yarn add react-native-splash-screen
react-native link react-native-splash-screen

Splash 이미지 만들기

Splash 스크린을 추가하기 전 Splash 스크린에 보여줄 이미지가 있어야겠죠? 우선 generator-rn-toolbox를 설치하겠습니다.

npm install -g yo generator-rn-toolbox

Yarn의 경우 yeoman을 설치하는데 일부 오류가 있어 npm을 사용해주세요. 그 다음 이미지를 만들기 위한 imagemagick을 설치해야합니다. https://imagemagick.org/script/download.php 에서 설치해주세요. 그 다음 스플래시 이미지를 만들겠습니다. 우선 스플래시 이미지로 사용할 이미지는 2208x2208 사이즈의 psd 파일로 준비해주세요. 그 다음 generator-rn-toolbox를 통해 안드로이드 스플래시 스크린을 만들겠습니다.

yo rn-toolbox:assets --splash [스플래시 파일 경로] --android

이제 스플래시 스크린 설정을 하겠습니다.

라이브러리 사용

제가 Windows 환경에서 개발 중인 관계로 Android, RN 부분 설정만 작성하도록 하겠습니다. 우선 React Native 내부의 Android 폴더를 Android Studio에서 열어주세요. Android Studio에서 작업하는 것이 더 편리합니다. 우선 MainActivity.java를 수정하겠습니다.

...
import com.facebook.react.ReactActivity;
import org.devio.rn.splashscreen.SplashScreen;
...
public class MainActivity extends ReactActivity {
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        SplashScreen.show(this);
        super.onCreate(savedInstanceState);
    }
}

우선 org.devio.rn.splashscreen.SplashScreen을 import 하신 다음 Android Studio, IntelliJ IDEA 기준 Ctrl + O를 누르시면 Override 할 수 있는 메소드를 확인하실 수 있습니다. 거기서 ReactActivity의 onCreate를 Override 하시고 SplashScreen.show(this); 를 추가해주세요.
그리고 res/layout/launch_screen.xml 을 생성하신 뒤 아래와 같이 적어주세요.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/launch_screen" android:scaleType="centerCrop" />
</RelativeLayout>

이제 RN에서 설정을 하겠습니다.

import React from 'react';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import Home from './pages/Home';
import Meal from './pages/Meal';
import Document from './pages/Document';
import Schedule from './pages/Schedule';
import Settings from './pages/Settings';

const Navigator = createBottomTabNavigator(
  {
    Home,
    Meal,
    Document,
    Schedule,
    Settings,
  },
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        const IconComponent = Ionicons;
        let iconName;

        switch (routeName) {
          case 'Home':
            iconName = `ios-home`;
            break;
          case 'Meal':
            iconName = 'ios-restaurant';
            break;
          case 'Document':
            iconName = 'ios-document';
            break;
          case 'Schedule':
            iconName = 'ios-calendar';
            break;
          case 'Settings':
            iconName = 'ios-settings';
            break;
          default:
            break;
        }

        return <IconComponent name={iconName} size={25} color={tintColor} />;
      },
    }),
    tabBarOptions: {
      activeTintColor: '#007ac1',
    },
  }
);

export default createAppContainer(Navigator);

기존 제 프로젝트의 App.js 코드입니다. React Navigation을 이용하기 때문에 createAppContainer를 export 하고 있습니다. 해당 코드를 수정하겠습니다.

import React, { useEffect } from 'react';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Ionicons from 'react-native-vector-icons/Ionicons';
import SplashScreen from 'react-native-splash-screen';
import Home from './pages/Home';
import Meal from './pages/Meal';
import Document from './pages/Document';
import Schedule from './pages/Schedule';
import Settings from './pages/Settings';

const Navigator = createBottomTabNavigator(
  {
    Home,
    Meal,
    Document,
    Schedule,
    Settings,
  },
  {
    defaultNavigationOptions: ({ navigation }) => ({
      tabBarIcon: ({ focused, horizontal, tintColor }) => {
        const { routeName } = navigation.state;
        const IconComponent = Ionicons;
        let iconName;

        switch (routeName) {
          case 'Home':
            iconName = `ios-home`;
            break;
          case 'Meal':
            iconName = 'ios-restaurant';
            break;
          case 'Document':
            iconName = 'ios-document';
            break;
          case 'Schedule':
            iconName = 'ios-calendar';
            break;
          case 'Settings':
            iconName = 'ios-settings';
            break;
          default:
            break;
        }

        return <IconComponent name={iconName} size={25} color={tintColor} />;
      },
    }),
    tabBarOptions: {
      activeTintColor: '#007ac1',
    },
  }
);

const AppContainer = createAppContainer(Navigator);

const App = () => {
  useEffect(() => {
    setTimeout(() => {
      SplashScreen.hide();
    }, 1000);
  }, []);

  return <AppContainer />;
};

export default App;

저는 이렇게 수정했습니다. Pure Functional Component를 사용하기 때문에 useEffect를 통해 처음 실행 시 1초 뒤 SplashScreen을 hide하는 코드를 작성했습니다. 저걸 네트워크 관련 코드로 처리해도 괜찮겠죠?

오늘은 이렇게 react-native-splash-screen을 사용하는법을 알아봤습니다.
읽어주셔서 감사합니다.