[Android] enableEdgeToEdge(), setOnApplyWindowInsetsListener()란?

thsamajiki·2024년 7월 25일
0

Android

목록 보기
5/5

Android Studio 버전을 Iguana로 업데이트한 다음부터 Activity가 생성되면 onCreate() 함수에 이전에는 없던 함수들이 보이기 시작해서 설명을 해보려고 한다.



enableEdgeToEdge()

먼저 enableEdgeToEdge() 메소드의 내부를 확인해보니 다음과 같다.

내부를 보면 이렇게 API Level에 따라 별도로 처리해주는 것을 확인할 수 있다.

맨 위에 있는 설명부터 번역하면 다음과 같다.

ComponentActivity에 대해서 edge-to-edge 디스플레이를 활성화할 수 있도록 해주는데, 이를 기본 스타일로 설정하기 위해서는 Activity의 onCreate() 메소드에서 enableEdgeToEdge() 메소드를 호출하면 된다.

기본 스타일은 시스템에 의해 대비가 적용될 수 있을 때(API 29 이상) 투명한 배경으로 System Bar를 구성합니다. 이전 플랫폼(3버튼/2버튼 탐색 모드만 있음)에서는 System Bar와의 대비를 보장하기 위해 동등한 배경(scrim)이 적용됩니다.

즉, 기존에는 테마에서 StatusBar나 NavigationBar의 스타일을 따로 지정해줘야 했지만, enableEdgeToEdge() 메소드를 호출하면 지정하지 않고도 해당 Bar들을 투명하게 만들거나 스타일을 지정할 수 있다는 것이다.

화면을 StatusBar와 NavigationBar까지 확장시키고 싶을 때, onCreate() 메소드 내에서 enableEdgeToEdge() 메소드를 사용할 수 있다.

💡 참고
scrim: [연극에서] 앞쪽에 빛을 비추면 불투명하고, 뒤쪽에 빛을 비추면 투명하거나 반투명하게 보이는 theater drop(극장에서 오르내리는 커튼)

SystemBarStyle

SystemBarStyle 클래스 위에 있는 주석을 번역하면 다음과 같다.

SystemBarStyle의 새 인스턴스를 만듭니다. 이 스타일은 다크 모드를 자동으로 감지하고 상태 표시줄과 탐색 표시줄 각각에 대해 권장되는 스타일을 적용합니다. 이 스타일이 앱에서 작동하지 않으면 다크 또는 라이트 중 하나를 사용하는 것을 고려하십시오.
API 레벨 29 이상에서는 상태 표시줄과 탐색 표시줄이 모두 투명하게 표시됩니다. 그러나 3개 또는 2개의 버튼이 있는 탐색 표시줄은 반투명한 scrim을 갖습니다. 이 scrim 색상은 플랫폼에서 제공하는 것이므로 사용자 지정할 수 없습니다.
API 레벨 28 이하에서는 상태 표시줄이 투명하게 표시되며 탐색 표시줄에는 다크 모드에 따라 지정된 scrim 색상 중 하나가 표시됩니다.

매개 변수:
lightScrim - 앱이 라이트 모드일 때 배경에 사용할 scrim 색상입니다. 이는 API Level 28 이하에서만 사용됩니다.
darkScrim - 앱이 다크 모드일 때 배경에 사용되는 scrim 색상입니다. 이는 시스템 아이콘 색상이 항상 밝은 장치에서도 사용됩니다. API Level 28 이하에서만 사용됩니다.
detect DarkMode - 옵션 UI가 현재 다크 모드를 사용하는지 여부를 감지합니다. 기본 구현은 platform, appcompat 및 Jetpack Compose에서 표준 다크 모드 기능을 감지할 수 있습니다.

API Level 29 이상에서는 auto 팩토리 함수를 사용해서 넣어주어도 지정된 색상이 반영되지 않는다. 만약 정말로 지정한 색상을 적용하고 싶다면 다음과 같이 dark나 light를 사용하여 style을 생성해야 한다.

override fun onCreate(savedInstanceState: Bundle?) {
	val lightColor = Color.parseColor("#ff6a00") // 주황색
	val darkColor = Color.parseColor("#ff6a80") // 핑크색

	// enableEdgeToEdge(statusBarStyle = SystemBarStyle.dark(scrim = darkColor)) // 반영 X
	// enableEdgeToEdge(statusBarStyle = SystemBarStyle.light(scrim = lightColor)) // 반영 X
	enableEdgeToEdge(
	statusBarStyle = SystemBarStyle.auto(lightScrim = lightColor, darkScrim = darkColor),
	navigationBarStyle = SystemBarStyle.auto(lightScrim = lightColor, darkScrim = darkColor),
	)
    
	binding.vLight.setBackgroundColor(lightColor)
	binding.vDark.setBackgroundColor(darkColor)
}

실제로도 그런지 테스트를 해보기 위해서
auto() 팩토리 함수로 SystemBarStyle을 생성하면서 라이트는 하늘색, 다크는 보라색으로 지정해주었다.

위 이미지와 같이 API Level 29 이상인 33에서는 StatusBar, NavigationBar가 모두 색상이 지정되지 않는 것을 확인할 수 있었다. 심지어 API Level 23 이상인 24에서는 NavigationBar가 darkColor로 지정되었다.

위의 팩토리 함수들을 보면 어떤 함수를 사용하느냐에 따라 SystemBarStyle에 들어가는 인자 값이 달라진다는 것을 확인할 수 있다. 특히 MODE가 중요했다.

auto()를 사용해서 style을 생성하는 경우, nightMode가 MODE_NIGHT_AUTO로 들어가게 된다는 것을 알아두자.

그리고(!) 잊지 말자!
enableEdgeToEdge()의 효과를 보려면 반드시 setContentView() 전에 호출해야 한다.

setOnApplyWindowInsetsListener

이 메소드도 내부를 확인해서 주석을 번역해보니 다음과 같다.

OnApplyWindowInsetListener를 설정하여 이 보기에 Windows 삽입을 적용하기 위한 정책을 이어받으십시오. 이는 API Level 21 이상을 사용하는 디바이스에서만 적용됩니다.

매개 변수:
view – listener.
listener – 적용된 창 세트의 listener에 대한 view.

앞서 설명한 enableEdgeToEdge() 함수가 StatusBar나 NavigationBar의 스타일을 지정하는 것과 달리, setOnApplyWindowInsetsListener() 함수는 view의 inset을 지정할 수 있다.
여기서 말하는 inset은 화면의 가장자리에 있는 SystemBar의 크기를 나타내는 측정값이다. onApplyWindowInsetsListener에서 inset값을 받아와서 padding, margin 값을 지정할 수 있다.



소감

Android Studio 버전을 업데이트하면서 Activity를 새로 생성할 때마다 매번 보이기 시작한 함수라서 궁금한 마음에 분석해봤다.
enableEdgeToEdge()가 StatusBar와 NavigationBar를 디자인하기에 좋은 함수인 것 같은데, 내부 동작 원리를 잘 이해하지 못하면 원하는 만큼 커스텀하기가 어려울 거라는 생각이 든다.



참고

https://developer.android.com/develop/ui/views/layout/edge-to-edge?hl=ko

profile
안드로이드 개발자

0개의 댓글