Android 15 (SDK 레벨 35) 이상을 타겟팅하는 앱은 안드로이드 15 이상인 기기에서 무조건 전체화면으로 실행되어요.
전체화면에 맞는 UI인지 아닌지는 알 바 아니고 무조건 전체화면으로 실행이 되는지라, 앱 디자인이 개판이 되거나, 일부 요소가 보이지 않는 현상이 발생해요.
Jetpack Compose에 있는 TopAppBar 같은 것을 사용하고 계셨다면, 아래에 있는 방법3이 자동으로 적용되고 있는 상태에요.
그래서 아마 디자인이 개판나지는 않을거예요.
방법 1. 대충 땜빵
안드로이드 15 미만을 타겟팅하도록 설정하면 되지만, 그러면 Play 스토어에 앱을 올리지 못해요.
"현재 출시된 안드로이드 최신버전으로부터 1년 이내에 출시된 버전"을 타겟팅해야 앱을 올릴 수 있어요.
기존에 올린 앱들도 최신 안드로이드를 타겟팅하는 업데이트를 출시하지 않으면, 검색해도 나오지 않거나 설치하지 못하게 구글이 막아버려요.
아주 잘 작동하고 아무런 문제가 없어도, 아무튼 구버전용이라 작동 안한다는 헛소리와 함께 설치나 검색 불가능
방법 2. 임시 땜빵
<style> 부분에 이런걸 적어주면 안드로이드 15까지는 대충 땜빵할 수 있어요.
<style 어쩌고저쩌고>
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
</style>
문제는 저건 안드로이드 16을 타겟팅하는 앱이 안드로이드 16에서 실행되는 경우는 작동하지 않아요.
게시글 작성 시점 기준으로, 안드로이드 15가 작년에 나왔고 요즘 폰들은 16이 설치되니 이제는 더 이상 사용하기에는 힘든 임시 땜빵 방식이에요.
방법 3. 시스템 영역 만큼 여백 넣기
건들면 알림창이 내려오고, 시간 등이 표시되는 윗부분은 status bar, 홉버튼, 뒤로가기 버튼 등이 있는 아래 부분은 navigation bar.
setContentView를 할 때 사용하는 view에다가 그 크기 만큼의 여백을 위아래에 넣으면 해결.
여기서 시스템 UI와 겹치지 않도록 필요한 화면 가장자리 여백을 대충 인셋이라고 불러요.
참고로, 앱과 겹치는 네이게이션 바의 불투명도는 80%
방법 3-1. ActionBar를 사용하는 경우
원래는 왼쪽 모습처럼 나와야 하지만, 오른쪽처럼 돼요.
액티비티의 내용물 윗부분이 액션바 아래로 들어가버리고, 네이게이션 바와 겹치게 표시되는 중

액티비티 안에 있는 view에 인셋만큼 여백을 넣어주면 해결
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
layout.setBackgroundColor(Color.CYAN);
TextView txt = new TextView(this);
txt.setText("TEST\nTEST\nTEST\nTEST\nTEST");
txt.setTextSize(32);
txt.setTextColor(Color.BLACK);
txt.setGravity(Gravity.CENTER);
layout.addView(txt);
setContentView(layout);
preventEdgeToEdge();
}
public void preventEdgeToEdge() {
View rootView = findViewById(android.R.id.content);
if (Build.VERSION.SDK_INT >= 35) rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
Insets sb = windowInsets.getInsets(WindowInsets.Type.systemBars());
view.setPadding(sb.left, sb.top, sb.right, sb.bottom);
return WindowInsets.CONSUMED;
}
});
}
}
setContentView(); 메서드의 인자로 넘긴 view가 액티비티 안에 바로 들어가는 것은 아니고, 액티비티 안에 뭐 안에 ... view 안에 넘긴 view가 들어가요.
액티비티와 넘긴 view 사이에 들어가는 것들은 Activity인지, AppCompatActivity인지에 따라 달라져요.
findViewById(android.R.id.content);은 FrameLayout를 반환하고, setContentView(); 메서드의 인자로 넘켰던 view가 그 안에 들어가있어요.
방법 3-2. ToolBar를 사용하는 경우
ToolBar는 왼쪽 사진처럼 위 아래가 싹 다 시스템 영역과 겹치는 상태로 나와요.
위에서 언급한 소스코드를 사용하면 오른쪽 사진처럼 ToolBar의 위가 비어버려요. 정확히는 기본 배경식인 흰색이 들어간거예요.

저 윗부분은 status bar가 아니기 때문에, status bar를 바꿀 때 사용하는 방식들은 전부 작동하지 않을거예요.
저 영역까지 findViewById(android.R.id.content);니까, findViewById(android.R.id.content);의 배경색을 설정하면 ToolBar 윗부분의 색을 설정할 수 있어요.
문제는 그러면 navigation bar 부분의 색도 함께 바뀌어요.
findViewById(android.R.id.content);의 아래 부분에 navigation bar 만큼의 margin을 주는 방식으로 해결하면 되긴 해요.
하지만, status bar와 크기가 동일한 뷰를 status bar 위치에 넣는 방식을 사용할거예요.
요약
액티비티 안에 있는 view에 인셋만큼 여백을 넣기. 상단 여백 제외
- 상단 여백도 넣으면 ToolBar 위가 비어버림
액티비티 안에 있는 view의 안에 있는 view에 인셋만큼 상단 여백 넣기
- 여기서 건드는 view는 setContentView의 인자로 넘겼던 view
status bar와 크기가 동일한 view를 ToolBar 위에 넣기
- 넣지 않는다면, ToolBar 윗부분의 색은 setContentView의 인자로 넘겼던 view의 배경색이 됨
public class TestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
layout.setBackgroundColor(Color.CYAN);
Toolbar title = new Toolbar(this);
title.setTitle("test");
title.setTitleTextColor(Color.WHITE);
title.setBackgroundColor(Color.parseColor("#212121"));
setActionBar(title);
layout.addView(title);
TextView txt = new TextView(this);
txt.setText("TEST\nTEST\nTEST\nTEST\nTEST");
txt.setTextSize(32);
txt.setTextColor(Color.BLACK);
txt.setGravity(Gravity.CENTER);
layout.addView(txt);
setContentView(layout);
preventEdgeToEdge();
}
public void preventEdgeToEdge() {
FrameLayout rootView = (FrameLayout)findViewById(android.R.id.content);
View contentView = rootView.getChildAt(0); //setContentView의 인자로 넘겼던 view
//status bar의 자리에 들어갈 view
View fakeStatusBar = new View(this);
fakeStatusBar.setBackgroundColor(Color.BLACK);
rootView.addView(fakeStatusBar, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 0));
if (Build.VERSION.SDK_INT >= 35) rootView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
Insets sb = windowInsets.getInsets(WindowInsets.Type.systemBars());
ViewGroup.LayoutParams params = fakeStatusBar.getLayoutParams();
params.height = sb.top; //status bar와 높이가 동일하도록 설정
fakeStatusBar.setLayoutParams(params);
//상단 여백 빼고 설정 - 여기에 여백이 들어가면 status bar 부분이 비어버림
rootView.setPadding(sb.left, rootView.getPaddingTop(), sb.right, sb.bottom);
//상단 여백만 설정 - 위에서 여백 설정했던 view의 자식 view
contentView.setPadding(contentView.getPaddingLeft(), sb.top, contentView.getPaddingRight(), contentView.getPaddingBottom());
return WindowInsets.CONSUMED;
}
});
}
}
setContentView();를 먼저 호출한 뒤에 preventEdgeToEdge();를 호출해야 해요.
실행 결과.

옛날에 colorPrimary로 ActionBar 배경색 넣고 colorPrimaryDark로 status bar 배경색을 조금 어둠게 설정하던 그 시절처럼 사용할 수 있어요.
대충 코틀린이 안드로이드 공식 개발 언어로 지정되기 이전 시절 이야기.
'Android 앱 개발' 카테고리의 다른 글
| 트릭컬 열차 추적기를 만들어보자 (1) | 2025.10.15 |
|---|---|
| 자바 & 코틀린 기초 요약 (4) | 2025.09.16 |
| 안드로이드 스튜디오 배경이 투명한 .png 이미지를 그대로 앱 아이콘으로 넣기 (5) | 2025.08.21 |