코틀린 & 컴포즈 & Java/컴포즈 Compose

[Compose] Scaffold: 내부 동작 원리와 UI 자동 조정 과정 분석

코딩하는후운 2025. 2. 25. 18:16
반응형

[Column + Scroll] 이나 lazyColumn 일 경우
멀티 윈도우 앱 크기 줄였을 때 스크롤 끊기는 현상이 있었습니다.

문제 재현

화면 기록 2025-02-25 오전 9.35.53.mov
3.98MB

 

결론부터 말하자면 Scaffold로 해결 하였습니다.

 

Scaffold란?

Scaffold는 앱의 기본 UI 구조를 제공하는 컨테이너 컴포저블입니다.

✔ topBar, bottomBar, floatingActionButton, drawerContent 등의 주요 UI 요소를 배치할 수 있도록 지원합니다.

✔ contentPadding을 통해 콘텐츠 영역의 크기를 자동 조정하여, UI가 겹치거나 잘리는 문제를 방지합니다.

✔ NestedScrollConnection을 활용해 내부 스크롤 이벤트 충돌을 방지하며, 시스템 UI(상태바, 네비게이션바)와의 겹침을 피하기 위해 Modifier.consumeWindowInsets()을 사용합니다.

 

Scaffold 내부 동작 원리: 어떻게 UI 크기를 자동 조정할까?

Scaffold의 핵심 기능

  1. topBar, bottomBar, floatingActionButton, drawerContent 등의 크기를 먼저 계산
  2. 남은 공간을 content 슬롯에 할당
  3. contentPadding을 생성하여 content 내부 요소가 UI와 겹치지 않도록 조정
Scaffold(
    topBar = { TopAppBar(title = { Text("홈") }) },
    bottomBar = { BottomNavigation { /* 하단 네비게이션 */ } },
    floatingActionButton = { FloatingActionButton(onClick = {}) { Text("+") } }
) { paddingValues -> // 🚀 contentPadding 자동 계산
    LazyColumn(
        modifier = Modifier
            .fillMaxSize()
            .padding(paddingValues) // 🚀 `topBar`, `bottomBar`와 겹치지 않도록 패딩 적용
    ) {
        items(100) { index -> Text("Item #$index") }
    }
}

💡 핵심
 Scaffold는 contentPadding을 적용하여 LazyColumn이 topBar 및 bottomBar와 겹치지 않도록 자동 조정합니다.
멀티윈도우에서 앱 크기가 줄어들어도 contentPadding이 다시 계산되면서 UI가 올바르게 배치됩니다.

 

contentPadding을 활용한 UI 크기 조정

contentPadding은 Scaffold 내부에서 UI 크기를 자동 조정하는 핵심 요소입니다.

이 contentPadding이 없으면 LazyColumn이 topBar 및 bottomBar과 겹쳐서 UI가 깨질 가능성이 큽니다.

contentPadding을 동적으로 계산하는 과정

val contentPadding = rememberInsetsPaddingValues(
    LocalWindowInsets.current.systemBars
)

 LocalWindowInsets.current.systemBars를 사용하여 시스템 바(상태바, 네비게이션바)와의 겹침을 방지  rememberInsetsPaddingValues()를 사용하여 패딩 값을 동적으로 저장하고 관리
 padding(contentPadding)을 content 내부 요소에 적용하여 크기를 자동 조정

 

Scaffold가 없는 경우, 스크롤 문제 발생

📌 멀티윈도우에서 Scaffold 없이 LazyColumn을 사용할 경우 발생하는 문제:

  • fillMaxSize()를 사용할 경우, LazyColumn이 ComposeView의 크기를 강제로 차지하면서 스크롤이 제한될 수 있음
  • nestedScroll()을 적용해도 부모 ComposeView가 스크롤 이벤트를 가로채어 멈추는 현상이 발생할 가능성이 높음
  • windowInsetsPadding()을 적용하지 않으면 시스템 UI(상태바, 네비게이션바)와 겹쳐서 높이 계산이 잘못될 가능성이 있음

📌 Scaffold를 사용하면?

  • contentPadding을 통해 자동으로 UI 크기를 조정하여 스크롤이 멈추지 않고 정상적으로 동작
  • LazyColumn이 contentPadding을 적용받아 topBar, bottomBar와 겹치지 않음
  • NestedScrollConnection 없이도 Scaffold 내부에서 올바르게 스크롤 이벤트를 처리

 

Scaffold의 내부 구조를 도식화하면?

✔ topBarbottomBar는 항상 고정
✔ content는 스크롤 가능하며, contentPadding을 적용하여 자동 조정
✔ FloatingActionButton은 자동으로 배치되며, LazyColumn과 겹치지 않도록 처리

 

Scaffold가 멀티윈도우에서 스크롤 문제를 해결하는 이유

Scaffold는 단순한 컨테이너가 아니라, UI 크기를 자동으로 조정하여 멀티윈도우에서도 정상적으로 동작하도록 보장하는 역할을 합니다!

  • contentPadding을 자동 적용하여, LazyColumn이 topBar 및 bottomBar과 겹치지 않도록 조정
  • Scaffold 내부에서 UI 크기를 자동으로 조정하여 멀티윈도우에서도 올바르게 동작
  • Modifier.consumeWindowInsets()를 활용하여 시스템 UI와 겹치지 않도록 설정
  • NestedScrollConnection 없이도 스크롤 이벤트를 올바르게 처리

 

 

반응형