Scaffold у Jetpack Compose — що це, властивості та як працює

Автор: IT Sectr Опубліковано: 2026-06-29 Час читання: 11 хв

Scaffold — це composable-функція в Jetpack Compose, яка реалізує базову структуру екрану за специфікацією Material Design. Scaffold надає слоти для TopAppBar, BottomBar, FloatingActionButton, Drawer та Snackbar. За даними Google Android Documentation, 2025, Scaffold є обов'язковим елементом більшості екранів у застосунках на Compose, оскільки керує відступами для системних компонентів Material Design.

Головне

  • Scaffold — каркас екрану Material Design, який надає слоти для TopAppBar, BottomBar, FAB, Drawer та Snackbar з коректними відступами.
  • ScaffoldState керує станом Drawer та Snackbar, забезпечуючи відкриття та закриття бокового меню та відображення сповіщень.
  • topBar, bottomBar та floatingActionButton — слоти Scaffold для інтеграції стандартних компонентів Material Design.
  • drawerGesturesEnabled керує жестом відкриття бокового меню, а snackbarHost — кастомним відображенням Snackbar.
  • Scaffold автоматично керує відступами для статус-бара та навігаційної панелі через innerPadding.

Що таке Scaffold у Jetpack Compose

Scaffold — це composable-функція, яка реалізує каркас екрану відповідно до специфікації Material Design. Scaffold не є контейнером у звичному розумінні — це менеджер макету, який координує розташування кількох стандартних компонентів Material на екрані.

Scaffold керує відступами для TopAppBar, BottomBar та FloatingActionButton, а також системними елементами — статус-баром та навігаційною панеллю. Це гарантує, що контент не перекривається системними елементами та відповідає гайдлайнам Material Design.

За даними Material Design Guidelines, 2025, Scaffold має бути кореневим елементом кожного екрану застосунку. Він замінює застарілий CoordinatorLayout з View-системи та надає простіший і декларативніший 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 автоматично додає відступ в innerPadding для контенту, щоб він не перекривався topBar. TopAppBar може містити заголовок, навігаційну іконку та дії.

bottomBar — слот для нижньої панелі навігації. Підтримує BottomNavigation, BottomAppBar або NavigationBar. Scaffold враховує висоту bottomBar при обчисленні innerPadding для контенту. За даними Material Design Guidelines, 2025, bottomBar слід використовувати на екранах з 3–5 точками навігації.

floatingActionButton — слот для плаваючої кнопки дії. Scaffold автоматично позиціонує FAB згідно зі специфікацією Material Design — у правому нижньому куті з коректним відступом. 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 — об'єкт стану Scaffold, який об'єднує DrawerState та SnackbarHostState. DrawerState керує відкриттям та закриттям бокового меню, а SnackbarHostState — відображенням та приховуванням Snackbar. Стан створюється через rememberScaffoldState() та передається в параметр scaffoldState.

DrawerState надає методи open та close для програмного керування Drawer. Стан 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 та Snackbar для відображення сповіщень при натисканні на FAB. 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 — це PaddingValues, які Scaffold передає в content-блок. Вони містять відступи, необхідні для того, щоб контент не перекривався statusBar, navigationBar, topBar та bottomBar. Використання innerPadding обов'язкове для коректного відображення на різних пристроях.

Scaffold автоматично обчислює innerPadding на основі системних відступів та висоти встановлених слотів. На пристроях з камерою-острівцем або вирізом в екрані Scaffold коригує відступи для статус-бара. На старих пристроях з фізичними кнопками відступ знизу може бути відсутнім.

За даними Android Developers, 2024, innerPadding слід застосовувати до кореневого контейнера контенту через Modifier.padding(innerPadding). Якщо контент використовує scrollable container, innerPadding застосовується через Modifier.consumeWindowInsets для коректної роботи клавіатури та системних жестів.

  • Застосовуйте innerPadding до кореневого контейнера контенту через Modifier.padding(innerPadding)
  • Для scrollable контейнерів використовуйте Modifier.consumeWindowInsets(innerPadding)
  • Не додавайте додаткові відступи для статус-бара — Scaffold робить це автоматично
  • При відсутності topBar або bottomBar відповідні відступи в innerPadding будуть нульовими

Часті запитання

Чим Scaffold відрізняється від звичайного Column або Box?

Scaffold — це не контейнер, а менеджер макету, який керує слотами для TopAppBar, BottomBar, FAB, Drawer та Snackbar, а також автоматично обробляє відступи для системних компонентів. Column та Box тільки розташовують елементи без урахування Material Design.

Чи обов'язково використовувати Scaffold на кожному екрані?

Scaffold рекомендується для екранів, що використовують компоненти Material Design. На простих екранах без TopAppBar, BottomBar або FAB Scaffold не обов'язковий, але він забезпечує коректні системні відступи через innerPadding, що корисно навіть без слотів.

Як показати Snackbar через Scaffold?

Передайте ScaffoldState в параметр scaffoldState Scaffold, потім викличте state.snackbarHostState.showSnackbar(“Повідомлення”) всередині корутини. Scaffold автоматично відобразить Snackbar у нижній частині екрану.

Чи можна використовувати Scaffold без scaffoldState?

Так, Scaffold створює внутрішній стан за замовчуванням, якщо scaffoldState не передано. Однак для керування Drawer та Snackbar програмно необхідно створити та передати ScaffoldState через rememberScaffoldState().

Як змінити положення FloatingActionButton у Scaffold?

Використовуйте параметр floatingActionButtonPosition Scaffold. За замовчуванням FAB знаходиться праворуч унизу (FabPosition.End). Встановіть FabPosition.Center для розміщення FAB у центрі нижнього краю екрану.

Підсумки

  • Scaffold — каркас екрану Material Design з керуванням слотами для TopAppBar, BottomBar, FAB, Drawer та Snackbar та автоматичними системними відступами.
  • topBar, bottomBar та floatingActionButton — слоти Scaffold для інтеграції стандартних компонентів із коректним позиціонуванням.
  • ScaffoldState об'єднує DrawerState та SnackbarHostState, забезпечуючи програмне керування боковим меню та сповіщеннями через корутини.
  • innerPadding — обов'язковий параметр content-блока, що містить відступи для системних елементів та встановлених слотів Scaffold.
  • drawerGesturesEnabled та floatingActionButtonPosition — додаткові параметри для тонкого налаштування поведінки Scaffold.
  • Scaffold автоматично обробляє відступи для статус-бара та навігаційної панелі на пристроях з різними конфігураціями екрану.
  • Для простих екранів без Material-компонентів Scaffold не обов'язковий, але рекомендується як кореневий елемент для коректної роботи системних відступів.

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також