Jetpack Compose의 Scaffold — 정의, 속성 및 작동 방식

저자: IT Sectr 게시일: 2026-06-29 읽는 시간: 11 분

Scaffold는 Material Design 사양에 따라 기본 화면 구조를 구현하는 Jetpack Compose의 composable 함수입니다. Scaffold는 TopAppBar, BottomBar, FloatingActionButton, Drawer 및 Snackbar를 위한 슬롯을 제공합니다. Google Android Documentation, 2025에 따르면 Scaffold는 Material Design 시스템 구성 요소의 여백을 관리하기 때문에 Compose 애플리케이션의 대부분 화면에서 필수 요소입니다.

핵심 사항

  • Scaffold는 올바른 여백으로 TopAppBar, BottomBar, FAB, Drawer 및 Snackbar를 위한 슬롯을 제공하는 Material Design 화면 프레임워크입니다.
  • ScaffoldState는 Drawer 및 Snackbar의 상태를 관리하여 사이드 메뉴 열기/닫기 및 알림 표시를 가능하게 합니다.
  • topBar, bottomBarfloatingActionButton은 표준 Material Design 구성 요소를 통합하기 위한 Scaffold 슬롯입니다.
  • drawerGesturesEnabled는 사이드 메뉴를 여는 스와이프 제스처를 제어하고, snackbarHost는 사용자 정의 Snackbar 표시를 제어합니다.
  • Scaffold는 innerPadding을 통해 상태 표시줄 및 탐색 표시줄의 여백을 자동으로 관리합니다.

Jetpack Compose에서 Scaffold란

Scaffold는 Material Design 사양에 따라 화면 프레임워크를 구현하는 composable 함수입니다. Scaffold는 전통적인 의미의 컨테이너가 아니라 화면에서 여러 표준 Material 구성 요소의 배치를 조정하는 레이아웃 관리자입니다.

Scaffold는 TopAppBar, BottomBar 및 FloatingActionButton의 여백을 관리하며 시스템 요소(상태 표시줄 및 탐색 표시줄)도 관리합니다. 이를 통해 콘텐츠가 시스템 요소와 겹치지 않고 Material Design 지침을 준수할 수 있습니다.

Material Design Guidelines, 2025에 따르면 Scaffold는 모든 앱 화면의 루트 요소여야 합니다. 이는 View 시스템의 레거시 CoordinatorLayout을 대체하고 화면 레이아웃을 구축하기 위한 더 간단하고 선언적인 API를 제공합니다.

기본 Scaffold 시그니처

Scaffold는 modifier, scaffoldState, topBar, bottomBar, floatingActionButton, drawerContent, snackbarHost 및 content 매개변수를 허용합니다. content 매개변수는 PaddingValues(기본 콘텐츠가 고려해야 할 여백)를 받습니다.

kotlin
@Composable
fun BasicScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("홈") }
            )
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)
        ) {
            Text("메인 콘텐츠")
        }
    }
}

Scaffold 슬롯: topBar, bottomBar 및 floatingActionButton

topBar는 앱 상단 바(일반적으로 TopAppBar 또는 LargeTopAppBar)를 배치하는 슬롯입니다. Scaffold는 콘텐츠가 topBar와 겹치지 않도록 innerPadding에 자동으로 여백을 추가합니다. TopAppBar에는 제목, 탐색 아이콘 및 작업이 포함될 수 있습니다.

bottomBar는 하단 탐색 표시줄을 위한 슬롯입니다. BottomNavigation, BottomAppBar 또는 NavigationBar를 지원합니다. Scaffold는 콘텐츠의 innerPadding을 계산할 때 bottomBar의 높이를 고려합니다. Material Design Guidelines, 2025에 따르면 bottomBar는 3~5개의 탐색 지점이 있는 화면에서 사용해야 합니다.

floatingActionButton은 플로팅 액션 버튼을 위한 슬롯입니다. Scaffold는 Material Design 사양에 따라 FAB를 자동으로 배치합니다(올바른 여백으로 오른쪽 하단 모서리). floatingActionButtonPosition을 사용하면 FAB를 화면 하단 가장자리 중앙으로 이동할 수 있습니다.

모든 슬롯을 사용한 예제

이 예제에서 Scaffold는 모든 주요 슬롯을 사용합니다: 제목이 있는 TopAppBar, 세 개의 탐색 항목이 있는 BottomBar 및 주요 작업을 위한 FloatingActionButton.

kotlin
@Composable
fun FullScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("앱") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Home, "홈") },
                    label = { Text("Home") },
                    selected = true,
                    onClick = {}
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Search, "검색") },
                    label = { Text("Search") },
                    selected = false,
                    onClick = {}
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("화면 콘텐츠")
        }
    }
}

ScaffoldState: Drawer 및 Snackbar 관리

ScaffoldState는 DrawerState와 SnackbarHostState를 결합한 Scaffold의 상태 객체입니다. DrawerState는 사이드 메뉴 열기 및 닫기를 관리하고 SnackbarHostState는 Snackbar 표시 및 숨기기를 관리합니다. 상태는 rememberScaffoldState()를 통해 생성되며 scaffoldState 매개변수에 전달됩니다.

DrawerState는 프로그래밍 방식 Drawer 제어를 위한 open 및 close 메서드를 제공합니다. Drawer 상태는 열림, 닫힘 또는 부분적으로 열림일 수 있습니다. drawerGesturesEnabled를 사용하면 Drawer를 여는 스와이프 제스처를 비활성화하고 버튼을 통한 프로그래밍 방식 열기만 남길 수 있습니다.

SnackbarHostState는 Snackbar(화면 하단의 임시 알림)를 관리합니다. showSnackbar 메서드는 메시지와 선택적 작업이 있는 Snackbar를 표시합니다. Material Design Guidelines, 2025에 따르면 Snackbar는 중요하지 않은 간단한 메시지에 사용해야 합니다.

kotlin
@Composable
fun ScaffoldWithDrawer() {
    val scaffoldState = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                title = { Text("메뉴") },
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        drawerContent = {
            Column(modifier = Modifier.padding(16.dp)) {
                Text("항목 1")
                Text("항목 2")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("콘텐츠")
        }
    }
}

Scaffold를 사용한 화면 구축 예제

Scaffold를 사용한 완전한 화면 예제에는 TopAppBar, BottomNavigation, FloatingActionButton 및 FAB 누를 때 알림을 표시하는 Snackbar가 포함됩니다. ScaffoldState는 상태 조정을 위해 모든 구성 요소에 전달됩니다.

kotlin
@Composable
fun MainScreen() {
    val state = rememberScaffoldState()
    val scope = rememberCoroutineScope()

    Scaffold(
        scaffoldState = state,
        topBar = {
            TopAppBar(
                title = { Text("IT Sectr") },
                actions = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Notifications, "Notifications")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(icon = { Icon(Icons.Default.Home, "홈") },
                    label = { Text("Home") }, selected = true, onClick = {})
                NavigationBarItem(icon = { Icon(Icons.Default.Settings, "설정") },
                    label = { Text("Settings") }, selected = false, onClick = {})
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {
                scope.launch {
                    state.snackbarHostState.showSnackbar("완료")
                }
            }) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { padding ->
        Box(
            modifier = Modifier.padding(padding).fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("환영합니다")
        }
    }
}

InnerPadding 및 Scaffold를 사용한 적응형 레이아웃

innerPadding은 Scaffold가 content 블록에 전달하는 PaddingValues입니다. 여기에는 콘텐츠가 statusBar, navigationBar, topBar 및 bottomBar와 겹치는 것을 방지하는 데 필요한 여백이 포함됩니다. 다른 기기에서 올바르게 표시하려면 innerPadding 사용이 필수입니다.

Scaffold는 시스템 여백과 설치된 슬롯의 높이를 기반으로 innerPadding을 자동으로 계산합니다. 카메라 아일랜드나 화면 컷아웃이 있는 기기에서 Scaffold는 상태 표시줄의 여백을 조정합니다. 물리적 버튼이 있는 구형 기기에서는 하단 여백이 없을 수 있습니다.

Android Developers, 2024에 따르면 innerPadding은 Modifier.padding(innerPadding)을 통해 콘텐츠의 루트 컨테이너에 적용해야 합니다. 콘텐츠가 스크롤 가능한 컨테이너를 사용하는 경우 키보드 및 시스템 제스처의 올바른 작동을 위해 innerPadding이 Modifier.consumeWindowInsets을 통해 적용됩니다.

  • Modifier.padding(innerPadding)을 사용하여 콘텐츠의 루트 컨테이너에 innerPadding 적용
  • 스크롤 가능한 컨테이너의 경우 Modifier.consumeWindowInsets(innerPadding) 사용
  • 상태 표시줄에 추가 여백을 추가하지 마세요 — Scaffold가 자동으로 처리합니다
  • topBar 또는 bottomBar가 없으면 innerPadding의 해당 여백은 0이 됩니다

자주 묻는 질문

Scaffold는 일반 Column이나 Box와 어떻게 다른가요?

Scaffold는 컨테이너가 아니라 TopAppBar, BottomBar, FAB, Drawer 및 Snackbar를 위한 슬롯을 제어하고 시스템 구성 요소의 여백을 자동으로 처리하는 레이아웃 관리자입니다. Column과 Box는 Material Design을 고려하지 않고 요소를 배치만 합니다.

모든 화면에서 Scaffold를 사용해야 하나요?

Scaffold는 Material Design 구성 요소를 사용하는 화면에 권장됩니다. TopAppBar, BottomBar 또는 FAB가 없는 단순한 화면에서는 Scaffold가 필수가 아니지만 innerPadding을 통해 올바른 시스템 여백을 제공하므로 슬롯이 없어도 유용합니다.

Scaffold를 통해 Snackbar를 표시하려면 어떻게 하나요?

Scaffold의 scaffoldState 매개변수에 ScaffoldState를 전달한 다음 코루틴 내에서 state.snackbarHostState.showSnackbar(“메시지”)를 호출합니다. Scaffold가 자동으로 화면 하단에 Snackbar를 표시합니다.

scaffoldState 없이 Scaffold를 사용할 수 있나요?

네, Scaffold는 scaffoldState가 전달되지 않으면 기본적으로 내부 상태를 생성합니다. 그러나 Drawer 및 Snackbar를 프로그래밍 방식으로 제어하려면 rememberScaffoldState()를 통해 ScaffoldState를 생성하고 전달해야 합니다.

Scaffold에서 FloatingActionButton 위치를 변경하려면 어떻게 하나요?

Scaffold의 floatingActionButtonPosition 매개변수를 사용합니다. 기본적으로 FAB는 오른쪽 하단(FabPosition.End)에 위치합니다. FabPosition.Center로 설정하면 FAB를 화면 하단 가장자리 중앙에 배치할 수 있습니다.

요약

  • Scaffold는 TopAppBar, BottomBar, FAB, Drawer 및 Snackbar를 위한 슬롯 관리와 자동 시스템 여백을 갖춘 Material Design 화면 프레임워크입니다.
  • topBar, bottomBarfloatingActionButton은 올바른 위치 지정으로 표준 구성 요소를 통합하기 위한 Scaffold 슬롯입니다.
  • ScaffoldState는 DrawerState와 SnackbarHostState를 결합하여 코루틴을 통해 사이드 메뉴 및 알림을 프로그래밍 방식으로 제어합니다.
  • innerPadding은 content 블록의 필수 매개변수로, 시스템 요소 및 설치된 Scaffold 슬롯의 여백을 포함합니다.
  • drawerGesturesEnabledfloatingActionButtonPosition은 Scaffold 동작을 미세 조정하기 위한 추가 매개변수입니다.
  • Scaffold는 다양한 화면 구성의 기기에서 상태 표시줄 및 탐색 표시줄의 여백을 자동으로 처리합니다.
  • Material 구성 요소가 없는 단순한 화면의 경우 Scaffold는 필수가 아니지만 올바른 시스템 여백 처리를 위해 루트 요소로 권장됩니다.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기