[Android] Android 15 대응 - EdgeToEdge: 3. WindowInsetsController

WindowInsetsController

setSystemUiVisibility가 deprecated되어 Android 15(API 35)부터는 WindowInsetsController 인터페이스를 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Inset 생성 시 Window를 제어하기 위한 인터페이스
*/
public interface WindowInsetsController {

/**
* 어두운 백그라운드, 밝은 포그라운드 색상을 가진 불투명한 상태표시줄을 만듦
* @hide
*/
int APPEARANCE_OPAQUE_STATUS_BARS = 1;
/**
* 어두운 백그라운드, 밝은 포그라운드 색상을 가진 불투명한 네비게이션 바를 만듦
* @hide
*/
int APPEARANCE_OPAQUE_NAVIGATION_BARS = 1 << 1;
/**
* 상태바 레이아웃이 변경됨 없이 덜 두드러지게 상태표시줄의 아이템을 적용함
* @hide
*/
int APPEARANCE_LOW_PROFILE_BARS = 1 << 2;
/**
* 밝은 상태표시줄로 변경하여 상태바 내 아이템들의 시연성을 뚜렷하게 함
*/
int APPEARANCE_LIGHT_STATUS_BARS = 1 << 3;
/**
* 밝은 네비게이션 바로 변경하여 상태바 내 아이템들의 시연성을 뚜렷하게 함
*/
int APPEARANCE_LIGHT_NAVIGATION_BARS = 1 << 4;

...
}

여기의 플래그를 보면 기존에 제공하던 아래 플래그와 전혀 다른 것을 알 수 있다.

1
2
3
4
5
6
7
8
decorView.systemUiVisibility = 
// 아래 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 와 중복?
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_FULLSCREEN or
// 가장 자리 스와이프 시 발동, 다만 앱에서는 인지 못함
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
// 하단 네비게이션 바 숨기기
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

여러 SDK 버전을 커버하는 WindowCompat 클래스에는 다음과 같이 분기처리가 되어 있다.

1
2
3
4
5
6
7
8
9
// Window의 Inset을 적용하는 경우 //
public static void setDecorFitsSystemWindows(@NonNull Window window,
final boolean decorFitsSystemWindows) {
if (Build.VERSION.SDK_INT >= 30) {
Api30Impl.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
} else {
Api16Impl.setDecorFitsSystemWindows(window, decorFitsSystemWindows);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static class Api16Impl {
private Api16Impl() {
// This class is not instantiable.
}
static void setDecorFitsSystemWindows(@NonNull Window window,
final boolean decorFitsSystemWindows) {
final int decorFitsFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
final View decorView = window.getDecorView();
final int sysUiVis = decorView.getSystemUiVisibility();
decorView.setSystemUiVisibility(decorFitsSystemWindows
? sysUiVis & ~decorFitsFlags
: sysUiVis | decorFitsFlags);
}
}
1
2
3
4
5
6
7
8
9
10
11
@RequiresApi(30)
static class Api30Impl {
private Api30Impl() {
// This class is not instantiable.
}
@DoNotInline
static void setDecorFitsSystemWindows(@NonNull Window window,
final boolean decorFitsSystemWindows) {
window.setDecorFitsSystemWindows(decorFitsSystemWindows);
}
}

이와 같이 Android 15(API 35) 이상에서는 Window의 Inset을 부분적으로 적용하는 경우, Window#setDecorFitsSystemWindows를 사용하면 된다.

인셋의 종류는 다음 세 가지이다.

  • System bars insets
  • Display cutout insets
  • System gesture insets

SystemBar 숨김/표시

1
2
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.show(WindowInsets.Type.systemBars())

이를 사용해 시스템바를 표시하거나(show) 숨길(hide) 수 있다.

Window Inset 제어를 통한 FullScreen 구현

  • [AndroidDev] 몰입형 모드를 위한 시스템 표시줄 숨기기

기존에 decorView에 systemUiVisibility 옵션을 주었던 것과는 달리 안드로이드 11(API 30)에 대응하기 위해서는 InsetsController를 이용해야 한다.

Android 11에서 기존 옵션에 매칭되는 사항은 다음과 같다.

  • WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_TOUCH: lean back
  • WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE: immersive
  • WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE: sticky immersive 최상단에서 쓸어내리거나 최하단에서 쓸어올리면 잠깐 나타나고 뷰에서 영역을 차지하지 않는다.

BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE를 적용한 예시 코드는 다음과 같다.

1
2
3
4
WindowCompat.getInsetsController(this, this.decorView).apply {
hide(WindowInsetsCompat.Type.navigationBars())
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
}

[Android] Android 15 대응 - EdgeToEdge: 3. WindowInsetsController

https://dl137584.github.io/2025/06/25/035-android15-edge-to-edge-03-windowinsetscontroller/

Author

LEEJS

Posted on

2025-06-25

Updated on

2026-01-10

Licensed under

댓글