블로그 목록
apps

Expo 앱 엣지 투 엣지 대응하기 — Android 15에서 콘텐츠가 상태바·내비게이션바에 가릴 때

Expo SDK 업그레이드하고 안드로이드 빌드를 돌렸더니, 화면 맨 위 콘텐츠가 상태바 뒤로 파고들고 아래쪽 버튼이 내비게이션 바에 반쯤 가려서 나왔다. iOS는 멀쩡했다. 뭘 잘못 만졌나 싶었는데, 알고 보니 내 코드 문제가 아니라 안드로이드 정책이 바뀐 거였다.

왜 갑자기 가릴까

Android 15(API 35)부터는 앱이 edge-to-edge로 그려지는 게 강제된다. 예전엔 상태바·내비게이션 바가 차지하는 영역을 시스템이 알아서 비워줬는데, 이제는 앱이 화면 전체를 꽉 채워서 그리고 그 위에 시스템 바가 반투명하게 얹힌다. 그래서 여백을 직접 안 잡아주면 콘텐츠가 바 뒤로 깔린다.

Expo도 SDK 52부터 이 동작이 기본값이 됐다. iOS는 원래 노치·홈 인디케이터 때문에 SafeArea를 챙겼으니 티가 안 났던 거고, 안드로이드만 뒤늦게 같은 문제를 맞은 셈이다.

SafeArea로 여백 잡기

해법은 결국 시스템 바가 먹는 영역만큼 padding을 넣는 거다. react-native-safe-area-contextuseSafeAreaInsets를 쓰면 상하좌우 inset 값을 픽셀로 준다.

import { useSafeAreaInsets } from 'react-native-safe-area-context';

function Screen() {
  const insets = useSafeAreaInsets();
  return (
    <View style={{ paddingTop: insets.top, paddingBottom: insets.bottom, flex: 1 }}>
      <Header />
      <Content />
      <SubmitButton />
    </View>
  );
}

SafeAreaView로 감싸도 되지만, 스크롤 영역은 콘텐츠가 바 밑까지 자연스럽게 흘러가는 게 예쁘다. 그럴 땐 컨테이너에 SafeAreaView를 쓰지 말고, ScrollView의 contentContainerStyle에만 paddingBottom: insets.bottom을 주는 식으로 세밀하게 조절하는 게 낫다.

시스템 바 색·스타일 제어

edge-to-edge에서는 바 배경색을 직접 못 칠한다. 대신 아이콘을 밝게/어둡게만 고를 수 있다. Expo에선 expo-status-barSystemBars(구버전은 StatusBar)로 처리한다.

import { SystemBars } from 'react-native-edge-to-edge';

// 밝은 배경 화면이면 아이콘을 어둡게
<SystemBars style="dark" />

react-native-edge-to-edge는 Expo가 내부적으로 쓰는 패키지인데, 바 스타일을 세밀하게 만질 일이 있으면 직접 설치해서 SystemBars를 쓰면 된다. 배경을 억지로 불투명하게 칠하려 하지 말고, 그냥 콘텐츠 색과 아이콘 대비만 맞춘다고 생각하는 게 마음 편하다.

정리

핵심은 세 줄이다. 화면을 꽉 채워 그리고, useSafeAreaInsets로 여백을 직접 잡고, 시스템 바는 색이 아니라 아이콘 스타일만 고른다. 새 SDK로 올린 뒤 안드로이드에서만 레이아웃이 깨져 보인다면 십중팔구 이 문제니까, SafeAreaProvider로 앱을 감쌌는지부터 확인해보자. 나는 그거 하나 빠뜨려서 한참 헤맸다.