“Android 로봇은 Google에서 제작하여 공유한 저작물을 복제하거나 수정한 것으로 Creative Commons 3.0 저작자 표시 라이선스의 약관에 따라 사용되었습니다.”
최근에 필자가 사용하던 갤럭시S23+ 을 Android 15로 업데이트 하였다.
업데이트 후 Compose로 만든 앱의 컨텐츠들이 상태바 영역부터 그려지는 일이 발생했다.
확인을 해보니 Android 15부터 API Level 35를 타겟팅하는 앱의 경우 기본적으로 edgeToEdge
가 활성화된다는 것이다. 개발자 문서
결국 이에 대한 대응이 필요했다.
edgeToEdge
란 상단 StatusBar 영역과 하단 NavigationBar 영역까지 컨텐츠가 표시되는 것을 의미한다.
더 넓은 영역까지 컨텐츠가 표시되니 더 많은 데이터를 표시할 수 있다는 이점이 있지만 디자인 설계에서 고려되지 않은 부분이 있다면 오히려 디자인을 해칠 수 있다.
그래서 적절한 처리가 필요하다.
다행히 Compose에서 Material3를 사용중이라면 자동 적용이 된다.
필자의 경우 Scaffold
내에서 NavigationBar
를 사용중이었고 AppBar
는 사용하지 않아서 상태바 영역 침범 문제에 대해서만 처리를 하였다.
다행히 WindowInsets
클래스를 사용하면 시스템 UI의 사이즈를 쉽게 가져올 수 있다.
아래의 적용한 소스를 같이 살펴보자
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() // 버전 상관없이 우선 일괄적으로 'edgeToEdge' 적용
super.onCreate(savedInstanceState)
initLauncher()
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
requestRole()
}
setContent {
Scaffold(
bottomBar = { BottomNavigationBar(navController = navHost, stateViewModel) },
floatingActionButton = {
if(currentRoute == MCScreenRoute.SpamList.route) {
ExpandedFab(stateViewModel)
}
}
) {
Column {
// Spacer를 상태바 크기로 지정하여 상태바 아래부터 컨텐츠가 그려지도록 구현
Spacer(modifier = Modifier.height(WindowInsets.statusBars.asPaddingValues().calculateTopPadding()))
AppNavHost(
navController = navHost,
paddingValues = it,
viewModel = viewModel,
stateViewModel = stateViewModel,
spamViewModel = spamInfoViewModel,
spamFilterViewModel = spamFilterViewModel
)
}
}
}
}
우선 enableEdgeToEdge()
를 호출하여 버전 상관없이 일괄적으로 적용한 후 Scaffold
Content에 Spacer
를 적용하여 상태바 영역 아래부터 컨텐츠가 보여질 수 있도록 하였다.
만일 필자처럼 모든 버전에 동일하게 적용하지 않고 Android 15 이상에서만 예외처리를 진행하고 싶다면 아래와 같이 분기를 추가하면 된다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initLauncher()
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
requestRole()
}
setContent {
Scaffold(
// Andorid 버전 분기하여 Modifier 할당
modifier = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars)
} else {
Modifier.fillMaxSize()
},
bottomBar = { BottomNavigationBar(navController = navHost, stateViewModel) },
floatingActionButton = {
if(currentRoute == MCScreenRoute.SpamList.route) {
ExpandedFab(stateViewModel)
}
}
) {
Column {
AppNavHost(
navController = navHost,
paddingValues = it,
viewModel = viewModel,
stateViewModel = stateViewModel,
spamViewModel = spamInfoViewModel,
spamFilterViewModel = spamFilterViewModel
)
}
}
}
}
단, 이렇게 할 경우 endgeToEdge
자체는 여전히 적용되어 있는 상태로 StatusBar와 NavigationBar는 투명색으로 되어있기 때문에 Theme.kt
로 이동하여 직접 색상을 추가적으로 지정해줘야한다.
edgeToEdge
자체를 해제하는 방법은 없는 것으로 보이고
구글에서도 정책적으로 강제하는 것처럼 보이기에..
개발자가 직접 Insets을 제어하는 방법 밖에 없어보인다.
개인적으로 공부했던 것을 바탕으로 작성하다보니
잘못된 정보가 있을수도 있습니다.
인지하게 되면 추후 수정하겠습니다.
피드백은 언제나 환영합니다.
읽어주셔서 감사합니다.