안녕하세요. 점냥입니다:)
오늘 포스팅 주제는 상태바의 투명하게, 반투명하게 만드는 방법에 대해서 포스팅해 보겠습니다!~
이 주제는 동아리에서 팀 프로젝트에서 상태바를 반 투명하게 만들려고 하는 과정에서 있었고 오랫동안 저의 머리를 골치 아프게 만들었습니다. ㅠㅠ 이번에 Android R(API 30)이 되면서 변경사항이 생기게 된 점도 다뤄보겠습니다!
상태바
상태바는 Android에 존재하는 여러 시스템 UI 중 하나이며 시간, 알람 등 디바이스의 정보를 아이콘으로 표시해 주는 역할을 수행합니다.
상태바 컬러 변경
<!-- This is the color of the Toolbar -->
<item name="colorPrimary">@color/primary</item>
<!-- This is the color of the Status bar -->
<item name="colorPrimaryDark">@color/primary_dark</item>
android의 ststus bar 컬러는 기본적으로 styles.xml의 colorPrimaryDark
속성을 따라갑니다.
따라서 가장 간단하게 해당 속성을 변경하여 status bar 색상을 변경을 시도할 수도 있는데요. 주의할 점은 여러 다른 material 컴포넌트의 색상에도 영향이 가므로 신중히 결정해야 합니다.
<item name="statusBarColor" tools:targetApi="21">@color/primary_dark</item>
Android API 21에서 Status bar 색상을 직접 설정할 수 있는 statusBarColor
속성이 나왔습니다.
따라서 만일 프로젝트 minSdkVersion이 21 미만이라면 targetApi
속성을 추가하거나 v21 식별자의 styles.xml을 추가해서 설정할 수 있습니다.
상태바 반투명 만들기
<item name="android:windowTranslucentStatus">true</item>
때로 상태바를 반투명, 투명으로 만들어야 하는 경우가 있는데요.
반투명 상태바는 Style의 windowTranslucentStatus
속성으로 쉽게 설정할 수 있지만 투명 상태바의 경우에는 몇 가지 추가 작업이 필요합니다.
상태바 투명 만들기
Activity의 Window는 기본적으로 Status bar와 BottomNavigation bar을 제외한 나머지 영역으로 설정되어 있습니다. 따라서 Content가 그려지는 영역을 상태바까지 확장해서 마치 상태바가 투명인 것처럼 구현하는 방법입니다.
이 방법은 우선 상태바 컬러를 Color.TRANSPARENT로 설정해야 합니다. 상태바 컬러는 statusBarColor 또는 Window 객체의 statusBarColor를 통해 설정할 수 있습니다. 이는 Android 21 이상부터 적용 가능한 방법이라는 뜻이기도 합니다.
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
targetSDK Android R 이전에서는 systemUiVisibility 속성을 통해 상태바 영역까지 확장할 수 있었습니다.
SYSTEM_UI_FLAG_LAYOUT_STABLE flag를 통해 안정적인 UI를 그릴 수 있도록 해주면서, SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN flag를 통해 전체 화면으로 확장시키는 코드입니다.
Android R 이후 상태바 투명으로 만들기
Android API 30이 되면서 systemUiVisibility 속성이 Deprecated 되었습니다. 대신 Window#setDecorFitsSystemWindows(boolean) 함수를 이용해서 구현할 수 있습니다.
◈ targetSdk가 30 이상이라면 WindowCompat을 사용해보세요. 버전 분기 없이 요구사항을 쉽게 구현할 수 있습니다.
WindowCompat.setDecorFitsSystemWindows(window, false)
상태바 컬러를 투명으로 변경하고 위 함수를 호출하면 systemUiVisibility을 사용해 구현했던 것처럼 Content가 Status Bar, Navigation Bar 영역까지 확장됩니다.
+ 추가 정보)
enableEdgeToEdge
새롭게 추가된 Activity의 enableEdgeToEdge 함수를 통해 위 요구사항을 구현할 수 있다고 합니다. 테마에 따라서 유동적으로 아이콘 컬러 대응을 해주면서 좀 더 편하게 확장 기능을 사용할 수 있다고 합니다.
상태바 투명으로 만들면서 UI 중복 케이스 대응
Content가 상태바 아래까지 확장되면서 투명한 상태바를 얻을 수 있었습니다. 하지만 시계, 배터리 등의 정보들이 그대로 포함되면서 기존 Content UI가 겹치는 케이스가 생길 수 있는데요.
ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
myView.updateLayoutParams<MarginLayoutParams>(
topMargin = insets.top
)
WindowInsetsCompat.CONSUMED
}
이 경우 setOnApplyWindowInsetsListener 콜백을 사용해 알맞은 뷰에 상태바의 높이만큼 다시 Top Padding을 적용하는 방법을 시도할 수 있습니다.
BottomNavigation Bar 영역까지 확장된 케이스 대응하기
setDecorFitsSystemWindows을 사용해서 상태바를 투명하게 구현했을 때, Content 영역이 상태바 뿐만 아니라 Navigation Bar 영역까지 확장된다는 것이 문제입니다. 그래서 만약 상태바만 투명으로 만들려고 한다면 Navigation Bar만큼 확장된 영역을 Padding으로 다시 채워주는 방법으로 해결할 수 있습니다.
ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, windowInsets ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
rootView.updateLayoutParams<MarginLayoutParams>(
bottomMargin = inset.bottom
)
WindowInsetsCompat.CONSUMED
}
참고
- https://soda1127.github.io/deep-dive-in-android-full-screen-2/
- https://developer.android.com/develop/ui/views/layout/edge-to-edge-manually?hl=ko
'Android > Common' 카테고리의 다른 글
[Android] LiveData의 Data를 한번만 관찰 (0) | 2021.03.15 |
---|---|
[Android] MVVM 적용하기 - View와 ViewModel (2) | 2021.03.10 |
[Android] Android Font 직접 적용 (0) | 2021.03.02 |
[Android] 딥 링크 - App Link (0) | 2021.02.16 |
[Android] 딥 링크 - URL Scheme (4) | 2021.02.08 |