어플을 개발할 때 상태바의 색상이 뷰의 백그라운드 컬러와 맞지 않아 불편할 때가 있다.
테마 스타일을 추가하여 상태바의 색상을 변경하거나 투명하게 만드는 방법을 알아보자.
values → themes.xml
<style name="Theme.SKUP.Splash">
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/mainBlue</item>
<item name="android:windowLightStatusBar">true</item>
</style>
android:statusBarColor
속성에 Color 값을 지정한다. 이 곳에 원하는 색상을 지정한다.
android:windowLightStatusBar
속성은 현재 상태바의 색상이 밝은 색인지 어두운 색인지를 설정한다. 이에 따라 상태바에 위치한 아이콘들을 어둡게 보여줄지 밝게 보여줄지 결정한다.
windowLightStatusBar의 값이 true
인 경우 아이콘을 어둡게 보여주고, false
인 경우 아이콘을 밝게 보여준다.
AndroidManifest.xml
<activity
android:name=".views.SplashActivity"
android:exported="true"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.SKUP.Splash">
...
<activity/>
Manifest 파일에 들어가 원하는 액티비티에 theme 값을 위에서 생성한 스타일로 지정해주면 된다.
한 프로젝트에서 스플래시 뷰의 백그라운드가 어두운 색이지만, 그 외의 모든 뷰의 백그라운드가 밝게 나오도록 개발해야 했었다. 이 경우 특정 액티비티에서만 상태바의 색상 조절이 필요했다.
본인의 한 프로젝트의 theme.xml 파일을 살펴보자
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.SKUP" parent="Theme.AppCompat.Light.NoActionBar">
<item name="windowNoTitle">true</item>
<!-- <item name="android:windowFullscreen">true</item>-->
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/white</item>
<item name="android:windowLightStatusBar">true</item>
<!-- Customize your theme here. -->
</style>
<style name="Theme.SKUP.Splash">
<!-- Status bar color. -->
<item name="android:statusBarColor">@color/mainBlue</item>
<item name="android:windowLightStatusBar">true</item>
</style>
</resources>
앱 전반에 적용되는 테마는 Theme.SKUP
이고, 스플래시뷰에 적용되는 테마는 Theme.SKUP.Splash
이다.
소스코드에 나와있는 것 처럼 Theme.SKUP 테마에서 뒤에 .을 붙여 테마를 상속받아서 특정 액티비티에서의 상태바만을 변경하였다.
또한 Theme.SKUP 테마는 Theme.AppCompat>Light.NoActionBar 테마를 상속받는다. 이때는 <style>
단에 parent로 상속받는 테마를 지정하였다.
이렇게 적용하면 Theme.SKUP 테마의 모든 속성을 유지하며 Theme.SKUP.Splash 에서 새로 지정한 값만 추가로 적용되게 할 수 있다. Manifest에 적용한 코드를 확인해보자.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:hardwareAccelerated="true"
android:icon="@mipmap/ic_skup_logo"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_skup_logo"
android:screenOrientation="portrait"
android:supportsRtl="true"
android:theme="@style/Theme.SKUP"
android:usesCleartextTraffic="true"
tools:targetApi="33">
<service
android:name=".service.NoticeNotificationService"
android:enabled="true"
android:exported="true"/>
<receiver
android:name=".service.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<activity
android:name=".views.SplashActivity"
android:exported="true"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.SKUP.Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
...
</application>
</manifest>
application 단 전체에 Theme.SKUP 테마를 적용하고 SplashActivity 단에만 Theme.SKUP.Splash 테마를 적용하여 상태바 색상 변경을 해결했다.
상태바의 색상을 변경하는 것은 해결했으나, 가끔은 아예 투명했으면 할 때가 있다. 이 때도 테마 스타일을 추가하고, 약간의 Kotlin 코드를 추가하여 구현해보자.
values → themes.xml
<style name="Theme.TransparentStatusBar" parent="Theme.Material3.Light.NoActionBar">
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
android:windowTranslucentStatus
속성을 true
로 주어 반투명한 상태바를 만들 수 있다.
하지만 우리가 원하는 것은 투명한 상태바임으로, Kotlin 코드를 추가하여 완전히 투명하게 변경해보자.
Activity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySplashBinding.inflate(layoutInflater)
setContentView(binding.root)
window.setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
)
...
}
window(액티비티 영역)를 외부 상태 표시줄까지 확장하는 것을 허락하는 Flag를 설정하여, 상태바가 투명해지는 효과를 적용할 수 있다.