Scaffold w Jetpack Compose — co to jest, właściwości i jak działa

Autor: IT Sectr Opublikowano: 2026-06-29 Czas czytania: 11 min

Scaffold — to funkcja composable w Jetpack Compose, implementująca podstawową strukturę ekranu zgodnie ze specyfikacją Material Design. Scaffold udostępnia sloty dla TopAppBar, BottomBar, FloatingActionButton, Drawer i Snackbar. Według Google Android Documentation, 2025, Scaffold jest obowiązkowym elementem większości ekranów w aplikacjach na Compose, ponieważ zarządza odstępami dla systemowych komponentów Material Design.

Najważniejsze

  • Scaffold — szkielet ekranu Material Design, który udostępnia sloty dla TopAppBar, BottomBar, FAB, Drawer i Snackbar z prawidłowymi odstępami.
  • ScaffoldState zarządza stanem Drawer i Snackbar, zapewniając otwieranie i zamykanie menu bocznego oraz wyświetlanie powiadomień.
  • topBar, bottomBar i floatingActionButton — sloty Scaffold do integracji standardowych komponentów Material Design.
  • drawerGesturesEnabled zarządza gestem otwierania menu bocznego, a snackbarHost — niestandardowym wyświetlaniem Snackbar.
  • Scaffold automatycznie zarządza odstępami dla paska statusu i panelu nawigacyjnego przez innerPadding.

Czym jest Scaffold w Jetpack Compose

Scaffold — to funkcja composable, implementująca szkielet ekranu zgodnie ze specyfikacją Material Design. Scaffold nie jest kontenerem w tradycyjnym sensie — to menedżer układu, który koordynuje rozmieszczenie kilku standardowych komponentów Material na ekranie.

Scaffold zarządza odstępami dla TopAppBar, BottomBar i FloatingActionButton, a także elementami systemowymi — paskiem statusu i panelem nawigacyjnym. Gwarantuje to, że treść nie zachodzi na elementy systemowe i jest zgodna z wytycznymi Material Design.

Według Material Design Guidelines, 2025, Scaffold powinien być głównym elementem każdego ekranu aplikacji. Zastępuje on przestarzały CoordinatorLayout z systemu View i zapewnia prostsze i bardziej deklaratywne API do budowania układu ekranu.

Podstawowa sygnatura Scaffold

Scaffold przyjmuje parametry modifier, scaffoldState, topBar, bottomBar, floatingActionButton, drawerContent, snackbarHost i content. Parametr content otrzymuje PaddingValues — odstępy, które musi uwzględnić główna treść.

kotlin
@Composable
fun BasicScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Strona główna") }
            )
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        }
    ) { innerPadding ->
        Column(
            modifier = Modifier.padding(innerPadding)
        ) {
            Text("Główna treść")
        }
    }
}

Sloty Scaffold: topBar, bottomBar i floatingActionButton

topBar — slot do umieszczenia górnego panelu aplikacji, zwykle TopAppBar lub LargeTopAppBar. Scaffold automatycznie dodaje odstęp w innerPadding dla treści, aby nie nachodziła na topBar. TopAppBar może zawierać tytuł, ikonę nawigacji i akcje.

bottomBar — slot dla dolnego panelu nawigacji. Obsługuje BottomNavigation, BottomAppBar lub NavigationBar. Scaffold uwzględnia wysokość bottomBar przy obliczaniu innerPadding dla treści. Według Material Design Guidelines, 2025, bottomBar powinien być używany na ekranach z 3–5 punktami nawigacji.

floatingActionButton — slot dla pływającego przycisku akcji. Scaffold automatycznie pozycjonuje FAB zgodnie ze specyfikacją Material Design — w prawym dolnym rogu z prawidłowym odstępem. floatingActionButtonPosition pozwala przenieść FAB na środek dolnej krawędzi ekranu.

Przykład ze wszystkimi slotami

W tym przykładzie Scaffold używa wszystkich głównych slotów: TopAppBar z tytułem, BottomBar z trzema elementami nawigacji i FloatingActionButton dla głównej akcji.

kotlin
@Composable
fun FullScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Aplikacja") },
                navigationIcon = {
                    IconButton(onClick = {}) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Home, "Strona główna") },
                    label = { Text("Home") },
                    selected = true,
                    onClick = {}
                )
                NavigationBarItem(
                    icon = { Icon(Icons.Default.Search, "Szukaj") },
                    label = { Text("Search") },
                    selected = false,
                    onClick = {}
                )
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {}) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("Treść ekranu")
        }
    }
}

ScaffoldState: zarządzanie Drawer i Snackbar

ScaffoldState — obiekt stanu Scaffold, który łączy DrawerState i SnackbarHostState. DrawerState zarządza otwieraniem i zamykaniem menu bocznego, a SnackbarHostState — wyświetlaniem i ukrywaniem Snackbar. Stan tworzony jest przez rememberScaffoldState() i przekazywany do parametru scaffoldState.

DrawerState udostępnia metody open i close do programowego zarządzania Drawer. Stan Drawer może być otwarty, zamknięty lub częściowo otwarty. drawerGesturesEnabled pozwala wyłączyć gest otwierania Drawer przeciągnięciem, pozostawiając tylko programowe otwieranie przez przycisk.

SnackbarHostState zarządza Snackbar — tymczasowymi powiadomieniami w dolnej części ekranu. Metoda showSnackbar wyświetla Snackbar z wiadomością i opcjonalną akcją. Według Material Design Guidelines, 2025, Snackbar powinien być używany do krótkich komunikatów bez krytycznie ważnych informacji.

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

    Scaffold(
        scaffoldState = scaffoldState,
        topBar = {
            TopAppBar(
                title = { Text("Menu") },
                navigationIcon = {
                    IconButton(onClick = {
                        scope.launch {
                            scaffoldState.drawerState.open()
                        }
                    }) {
                        Icon(Icons.Default.Menu, "Menu")
                    }
                }
            )
        },
        drawerContent = {
            Column(modifier = Modifier.padding(16.dp)) {
                Text("Element 1")
                Text("Element 2")
            }
        }
    ) { innerPadding ->
        Box(modifier = Modifier.padding(innerPadding)) {
            Text("Treść")
        }
    }
}

Przykład budowy ekranu ze Scaffold

Pełny przykład ekranu ze Scaffold obejmuje TopAppBar, BottomNavigation, FloatingActionButton i Snackbar do wyświetlania powiadomień po naciśnięciu FAB. ScaffoldState jest przekazywany do wszystkich komponentów w celu koordynacji stanu.

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, "Strona główna") },
                    label = { Text("Home") }, selected = true, onClick = {})
                NavigationBarItem(icon = { Icon(Icons.Default.Settings, "Ustawienia") },
                    label = { Text("Settings") }, selected = false, onClick = {})
            }
        },
        floatingActionButton = {
            FloatingActionButton(onClick = {
                scope.launch {
                    state.snackbarHostState.showSnackbar("Gotowe")
                }
            }) {
                Icon(Icons.Default.Add, "Add")
            }
        }
    ) { padding ->
        Box(
            modifier = Modifier.padding(padding).fillMaxSize(),
            contentAlignment = Alignment.Center
        ) {
            Text("Witaj")
        }
    }
}

InnerPadding i adaptacyjny layout ze Scaffold

innerPadding — to PaddingValues, które Scaffold przekazuje do bloku content. Zawierają one odstępy niezbędne do tego, aby treść nie nachodziła na statusBar, navigationBar, topBar i bottomBar. Użycie innerPadding jest obowiązkowe dla prawidłowego wyświetlania na różnych urządzeniach.

Scaffold automatycznie oblicza innerPadding na podstawie odstępów systemowych i wysokości zainstalowanych slotów. Na urządzeniach z wyspą kamerki lub wycięciem w ekranie Scaffold koryguje odstępy dla paska statusu. Na starszych urządzeniach z fizycznymi przyciskami dolny odstęp może być zerowy.

Według Android Developers, 2024, innerPadding powinien być stosowany do głównego kontenera treści przez Modifier.padding(innerPadding). Jeśli treść używa kontenera przewijanego, innerPadding stosuje się przez Modifier.consumeWindowInsets do prawidłowej pracy klawiatury i gestów systemowych.

  • Stosuj innerPadding do głównego kontenera treści przez Modifier.padding(innerPadding)
  • Dla kontenerów przewijanych używaj Modifier.consumeWindowInsets(innerPadding)
  • Nie dodawaj dodatkowych odstępów dla paska statusu — Scaffold robi to automatycznie
  • W przypadku braku topBar lub bottomBar odpowiednie odstępy w innerPadding będą zerowe

Często zadawane pytania

Czym Scaffold różni się od zwykłego Column lub Box?

Scaffold — to nie kontener, a menedżer układu, który zarządza slotami dla TopAppBar, BottomBar, FAB, Drawer i Snackbar, a także automatycznie przetwarza odstępy dla komponentów systemowych. Column i Box tylko rozmieszczają elementy bez uwzględniania Material Design.

Czy stosowanie Scaffold na każdym ekranie jest obowiązkowe?

Scaffold jest zalecany dla ekranów korzystających z komponentów Material Design. Na prostych ekranach bez TopAppBar, BottomBar lub FAB Scaffold nie jest obowiązkowy, ale zapewnia prawidłowe systemowe odstępy przez innerPadding, co jest przydatne nawet bez slotów.

Jak wyświetlić Snackbar przez Scaffold?

Przekaż ScaffoldState do parametru scaffoldState Scaffold, a następnie wywołaj state.snackbarHostState.showSnackbar(„Wiadomość”) wewnątrz korutyny. Scaffold automatycznie wyświetli Snackbar w dolnej części ekranu.

Czy można używać Scaffold bez scaffoldState?

Tak, Scaffold tworzy wewnętrzny stan domyślnie, jeśli scaffoldState nie został przekazany. Jednak do programowego zarządzania Drawer i Snackbar należy utworzyć i przekazać ScaffoldState przez rememberScaffoldState().

Jak zmienić położenie FloatingActionButton w Scaffold?

Użyj parametru floatingActionButtonPosition Scaffold. Domyślnie FAB znajduje się po prawej stronie na dole (FabPosition.End). Ustaw FabPosition.Center, aby umieścić FAB na środku dolnej krawędzi ekranu.

Podsumowanie

  • Scaffold — szkielet ekranu Material Design z zarządzaniem slotami dla TopAppBar, BottomBar, FAB, Drawer i Snackbar oraz automatycznymi odstępami systemowymi.
  • topBar, bottomBar i floatingActionButton — sloty Scaffold do integracji standardowych komponentów z prawidłowym pozycjonowaniem.
  • ScaffoldState łączy DrawerState i SnackbarHostState, zapewniając programowe zarządzanie menu bocznym i powiadomieniami przez korutyny.
  • innerPadding — obowiązkowy parametr bloku content, zawierający odstępy dla elementów systemowych i zainstalowanych slotów Scaffold.
  • drawerGesturesEnabled i floatingActionButtonPosition — dodatkowe parametry do precyzyjnego dostrajania zachowania Scaffold.
  • Scaffold automatycznie przetwarza odstępy dla paska statusu i panelu nawigacyjnego na urządzeniach z różnymi konfiguracjami ekranu.
  • Dla prostych ekranów bez komponentów Material Scaffold nie jest obowiązkowy, ale jest zalecany jako główny element do prawidłowego działania odstępów systemowych.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również