모든 글
Android · 2분 읽기

안드로이드를 만들며 12 — 광고가 이상한 줄 알았더니 위의 Scaffold가 둘이었어요

하단 광고 배너 아래에 정체불명의 빈 여백이 생겼습니다. 광고 뷰의 픽셀을 의심했지만, 원인은 화면 상단에 겹쳐 있던 2중 Scaffold와 두 번 더해진 윈도우 인셋이었습니다. 눈에 보이는 자리와 원인이 있는 자리를 분리해 디버깅한 기록입니다.

#안드로이드#compose#scaffold#인셋#ui버그

화면 하단에 AdMob 적응형 배너를 붙였는데, 기기 하단 내비게이션 바와 광고 사이에 정체불명의 빈 띠(여백)가 생겼습니다.

처음에는 누구나 광고 컴포넌트를 의심합니다.

  • “AdMob SDK의 Adaptive Banner 높이 계산 공식이 틀렸나?”
  • “광고를 감싼 AndroidViewlayout_heightwrap_content라서 그런가?”
  • “기기 화면 해상도(DPI) 변환 과정에서 오차가 났나?”

실제로 광고 컨테이너의 픽셀을 레이아웃 인스펙터로 찍어보았습니다. Box, FrameLayout, AdView 모두 정확히 1078 × 168 px을 가리키고 있었습니다. 광고는 1픽셀의 오차도 없이 완벽하게 제 크기를 지키고 있었습니다.

빈 띠를 만든 것은 광고 위의 2중 Scaffold

문제는 광고 뷰 자체가 아니라, 화면 트리를 감싸고 있던 상위 구조에 있었습니다.

// 최상위 앱 내비게이션 레벨
Scaffold(
    bottomBar = { /* ... */ }
) { paddingValues ->
    // 각 탭별 개별 화면 레벨
    Scaffold(
        modifier = Modifier.padding(paddingValues) // 1차 시스템 인셋 적용
    ) { innerPadding ->
        // 콘텐츠 화면
        Column(modifier = Modifier.padding(innerPadding)) { // 2차 시스템 인셋 또 적용!
            ...
            AdBanner()
        }
    }
}

Compose에서 Scaffold는 시스템 윈도우 인셋(네비게이션 바, 상태 표시줄 높이)을 계산해 innerPadding으로 넘겨줍니다.

그런데 메인 프레임에 Scaffold가 있고, 그 자식 화면 안에 또 Scaffold를 선언하면서 하단 시스템 인셋(Navigation Bar Inset)이 두 번 더해지고 있었던 것입니다.

광고 밑의 빈 띠는 광고가 밀어낸 것이 아니라, 두 겹의 Scaffold가 만들어낸 유령 여백이었습니다.

하나를 찾으면 나머지를 세는 일이 뒤따릅니다

이 버그를 잡고 나서 곧바로 화면 전체를 훑었습니다. 경험상 이런 구조적 실수는 단 한 화면에만 머물지 않기 때문입니다.

전수 조사를 해보니 유사한 ‘화면 복제 버그 4종 세트’가 곳곳에 숨어 있었습니다.

  1. 뷰어 뒤로가기 시트 재노출 버그: PDF 뷰어에서 뒤로가기 키를 눌러 나왔을 때 결과 바텀시트가 닫히지 않고 다시 뜨는 현상 (4개 화면)
  2. 하단 인셋 2중첩 여백: 바텀시트와 화면 본문에서 시스템 패딩이 2중으로 먹던 현상 (3개 화면)
  3. 빈 상태(Empty State) 정렬 어긋남: 데이터가 없을 때 표시되는 일러스트가 위로 치우치던 현상 (2개 화면)
  4. 회전 시 아이콘 상태 꼬임: 기기 회전 시 툴바 액션 아이콘의 상태가 초기화되던 현상

하나를 고쳤을 때 “혹시 다른 화면에도 이 패턴이 있는가?”를 전수 조사하지 않으면, 우리는 버그의 25%만 고치고 퇴근하는 셈이 됩니다.

눈에 보이는 자리와 원인이 있는 자리를 분리하기

UI 디버깅에서 가장 위험한 함정은 “문제가 보이는 시각적 위치에 원인 코드가 있을 것”이라는 선입견입니다.

  • 하단 광고가 이상해 보인다고 광고 뷰의 패딩을 마이너스로 깎는 행위
  • 바텀시트가 겹친다고 임의의 Spacer(height = 16.dp)를 쑤셔 넣는 행위

이런 처방은 근본 원인(2중 Scaffold)을 가려버리고, 나중에 다른 기기나 화면 크기에서 레이아웃이 완전히 깨지는 2차 재앙을 낳습니다.

결국 바꾼 것

  • 보이는 자리와 원인이 있는 자리는 다릅니다. 픽셀을 측정하여 결백한 컴포넌트를 먼저 증명하세요.
  • Compose에서 Scaffold를 중첩할 때는 WindowInsets 전달 경로와 paddingValues 소비 여부를 엄격히 확인해야 합니다.
  • 버그를 하나 잡았다면 반드시 전체 저장소에서 같은 패턴을 검색하세요. 하나가 발견된 자리는 보통 네 군데로 복제되어 있습니다.