Uing? Uing!!

[내 맘대로 정리한 안드로이드] 스플래시(Splash) 화면은 어떻게 만들어야 효율적으로 활용할 수 있을까? 본문

Android

[내 맘대로 정리한 안드로이드] 스플래시(Splash) 화면은 어떻게 만들어야 효율적으로 활용할 수 있을까?

Uing!! 2020. 8. 3. 17:39
반응형

 

 

스플래시(Splash) 화면과 그 목적

스플래시 화면은 앱의 본격적인 화면이 나오기 전에 1~2초 간 잠시 나타나는 화면이다.

일반적으로 단색 배경에 어플리케이션의 로고가 중앙에 표시되는 경우가 많다.

 

이 화면은 왜 필요한 걸까?

일단 디자인적인 이유가 있을 수 있다.

브랜드나 앱 이미지를 각인시키기 위해서.

 

하지만 Splash 화면의 주 목적은 따로 있다.

스플래시 화면이 없는 어플리케이션을 열어 보면, 메인 화면이 표시되기 전에 0.x초동안 텅 빈 화면이 나타난다.

짧은 시간이지만 이렇게 텅 빈 화면이 나타나는 것은 분명히 보기 좋은 현상은 아니다.

Splash 화면은 이러한 공백을 채우기 위해 제작된다.

 

Q. 왜 빈 화면이 뜨는 것일까?

공백을 지우기 위해 Splash를 만들기 전에, 이 공백은 왜 생기는 걸까?

이는 안드로이드의 어플리케이션 실행 순서와 관련이 있다.

 

처음 Application을 실행하면, 첫 Activity의 onCreate()가 실행되기 전에 setTheme()이라는 친구가 먼저 실행된다.

이 setTheme()은 액티비티에 테마(theme)가 지정되어 있으면 테마를 표시하는 메서드이다.

setTheme() -> onCreate() 순으로 호출되기 때문에 테마가 먼저 나타난 후, 화면 layout이 불러와지는 것이다.

 

그런데 theme이 지정되어 있지 않다면?

어쨌거나 setTheme()이 먼저 호출되는데, 이때는 빈 화면이 나타난다.

그리고 우리의 MainActivity에는 기본적으로 이 공백을 채우기 위한 theme이 따로 지정되어 있지 않다.

그렇기 때문에 setTheme()과 onCreate의 layout inflation 사이에 빈 화면이 나타나는 것이다.

 

그렇다면 해결 방법은 간단하다.

첫 Activity에 theme을 설정해 주는 것이다.

 

Q. 예제에서는 그냥 SplashActivity 만들어서 2초 기다리고 MainActivity 시작하던데...?

내가 처음 따라했던 Splash 화면의 예제가 그랬다. 대충 이런 코드였다. 

(초반에 스토어에 런칭한 앱들에는 아직도 이런 Splash가 적용되어 있어서 조금 부끄럽다...)

 

SplashActivity.kt

class SplashActivity : AppCompatActivity() {
    internal var handler = Handler()

    /** Called when the activity is first created.  */
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        handler.postDelayed({
        	val intent = Intent(baseContext, MainActivity::class.java)
        	startActivity(intent)
        	finish()
        }, 2000)
    }
}

AndroidManifest.xml

        <activity
            android:name=".SplashActivity"
            android:configChanges="keyboardHidden|orientation"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

 

AndroidManifest에서 intent 필터로 SplashActivity를 첫 화면으로 설정한 것까진 그렇다고 치자.

그런데 코드를 보면, Splash 화면인데 일반적인 Activity와 똑같이 layout xml파일을 불러온다.

그리고는 그냥 2초를 버린 다음 MainActivity를 시작한다.

 

이러면 사실...... Splash 화면 본연의 의미는 완전히 잃어버리게 된다.

왜? 앞의 내용과 같이 Splash화면은 처음 앱 실행 시의 로딩시간을 지워 주는 데에 그 목적이 있다.

근데 이 코드는 그냥 시작 화면만 Splash로 바꼈다 뿐이지, SplashActivity 화면을 불러오는 데 결국 0.x초가 그대로 든다.

이래서는 그냥 2초를 생으로 날린 것밖에 되지 않는다. 로고를 박았으니 이미지야 각인시켰겠지만 말이다.

 

그렇다면 어떻게 하는 것이 Splash의 효율적인 구현 방법일까?

앞에서 이야기했었듯이, theme을 설정해 주면 된다.

 

Theme을 활용해서 Splash 만들기

서론이 길었는데 다음은 실제 구현에 대한 내용이다!

위에서 제시된 '2초 기다리기' 방식은 비효율적이고 Splash의 의미도 없다.

SplashActivity를 만든다고 해서 첫 setTheme()과 onCreate() 사이의 공백이 사라지지는 않기 때문이다.

 

애초에 SplashActivity 자체가 필요하지도 않다.

우리가 원하는 건 본 화면이 불러와지기 전의 '찰나'에 Splash 화면을 보여주는 것이다.

이 찰나를 위해 SplashActivity라는 새로운 액티비티를 만드는 것은 불필요한 작업일 수 있다.

 

그래서 개인적으로 가장 효율이 좋다고 생각하는 방법은 MainActivity만을 사용하는 방법이다.

MainActivity의 기본 테마를 로고가 박힌 Splash 화면에 해당하는 SplashTheme으로 설정해 버린 후,

화면 로딩 이후에 본래의 테마로 돌려 놓는 것이다.

 

기존의 '2초 기다리기' 방법에 비해 말은 길지만 구현이 어렵지는 않다.

아래 순서(1~4)를 따라 작성하면 된다.

 

1. Splash 화면의 배경으로 활용될 배경 xml을 만든다.

우선 배경으로 쓸 화면을 layout이 아닌 drawable로 생성해주어야 한다.

res > drawable에 background_splash.xml 파일을 생성한 후, 아래처럼 splash 화면을 작성한다.

이 xml에서는 colors.xml에 정의된 colorPrimary 색을 배경으로 하고, 가운데에 splash_icon이 추가되어 있다.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/colorPrimary"/>
    <item>
        <bitmap
            android:src="@drawable/splash_icon"
            android:gravity="center" />
    </item>
</layer-list>

2. styles.xml에서 SplashTheme을 설정한다.

테마(theme)는 res > values 위치의 styles.xml 파일에 작성된다.

이 파일에 접근한 뒤 아래처럼 SplashTheme이라는 새로운 style을 추가한다.

이 style의 배경은 1번에서 만든 background_splash.xml이고, 화면 내에는 title bar가 없고, status bar는 배경색과 같다.

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- No Title Bar-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!-- white status bar -->
        <item name="android:statusBarColor">@color/colorPrimary</item>
        <item name="android:windowLightStatusBar">true</item>
    </style>
    <!-- Splash theme. -->
    <style name="SplashTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!-- No Title Bar-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
        <!-- white status bar -->
        <item name="android:statusBarColor">@color/colorPrimary</item>
        <item name="android:windowLightStatusBar">true</item>
        <!-- background -->
        <item name="android:windowBackground">@drawable/background_splash</item>
    </style>
</resources>

3. MainActivity의 기본 Theme을 바꾼다.

각 액티비티의 Theme은 AndroidManifest.xml파일에서 지정할 수 있다.

AndroidManifest.xml에서 MainActivity의 내용에서 android:theme="@style/SplashTheme"으로 설정해 준다.

        <activity android:name=".ui.main.MainActivity"
            android:theme="@style/SplashTheme"
            android:configChanges="orientation|screenSize|keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.VIEW" />
            </intent-filter>
        </activity>

4. MainActivity.kt에서 화면 로딩 후 Theme을 돌려 놓게 한다.

MainActivity 파일의 onCreate()가 실행되었다는 것은 이제 화면이 로딩될 준비가 완료되었다는 것이다.

그러므로, onCreate()를 시작하자마자 SplashTheme에서 원래의 AppTheme으로 돌려놓는다.

setTheme() 메서드를 활용해 아래와 같이 작성할 수 있다.

    override fun onCreate(savedInstanceState: Bundle?) {
        setTheme(R.style.AppTheme)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
   

 

이렇게 Splash를 설정해준 후 어플리케이션을 실행하면,

잠시 스플래시 화면이 나타났다가 바로 본 화면으로 넘어간다.

 

Splash 화면을 설정하는 데에는 여러 가지 방법이 있을 수 있지만,

개인적으로는 이 방법이 가장 효율성이 좋다고 생각하고 있다.

반응형
Comments