[Column + Scroll] 이나 lazyColumn 일 경우
멀티 윈도우 앱 크기 줄였을 때 스크롤 끊기는 현상이 있었습니다.
문제 재현
결론부터 말하자면 Scaffold로 해결 하였습니다.
Scaffold란?
Scaffold는 앱의 기본 UI 구조를 제공하는 컨테이너 컴포저블입니다.
✔ topBar, bottomBar, floatingActionButton, drawerContent 등의 주요 UI 요소를 배치할 수 있도록 지원합니다.
✔ contentPadding을 통해 콘텐츠 영역의 크기를 자동 조정하여, UI가 겹치거나 잘리는 문제를 방지합니다.
✔ NestedScrollConnection을 활용해 내부 스크롤 이벤트 충돌을 방지하며, 시스템 UI(상태바, 네비게이션바)와의 겹침을 피하기 위해 Modifier.consumeWindowInsets()을 사용합니다.
Scaffold 내부 동작 원리: 어떻게 UI 크기를 자동 조정할까?
Scaffold의 핵심 기능
- topBar, bottomBar, floatingActionButton, drawerContent 등의 크기를 먼저 계산
- 남은 공간을 content 슬롯에 할당
- 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의 내부 구조를 도식화하면?
✔ topBar, bottomBar는 항상 고정
✔ content는 스크롤 가능하며, contentPadding을 적용하여 자동 조정
✔ FloatingActionButton은 자동으로 배치되며, LazyColumn과 겹치지 않도록 처리
Scaffold가 멀티윈도우에서 스크롤 문제를 해결하는 이유
Scaffold는 단순한 컨테이너가 아니라, UI 크기를 자동으로 조정하여 멀티윈도우에서도 정상적으로 동작하도록 보장하는 역할을 합니다!
- contentPadding을 자동 적용하여, LazyColumn이 topBar 및 bottomBar과 겹치지 않도록 조정
- Scaffold 내부에서 UI 크기를 자동으로 조정하여 멀티윈도우에서도 올바르게 동작
- Modifier.consumeWindowInsets()를 활용하여 시스템 UI와 겹치지 않도록 설정
- NestedScrollConnection 없이도 스크롤 이벤트를 올바르게 처리
'코틀린 & 컴포즈 & Java > 컴포즈 Compose' 카테고리의 다른 글
[Compose] 스크롤 안에 (뷰 페이저 + 스크롤) 있는 경우 (0) | 2025.02.25 |
---|---|
[Compose] 컴포즈 실전 내가 경험한 Tip ! (0) | 2025.02.25 |
[Compose] UI를 구성할 때 요소를 정렬하는 방법 (0) | 2025.02.10 |
[Compose] LiveData vs StateFlow: Compose에서 어떤 것을 사용할까? (0) | 2025.02.06 |
[Compose] Compose에서 key의 역할과 사용법 (0) | 2025.02.06 |