Scaffold es una función composable en Jetpack Compose que implementa la estructura básica de pantalla según la especificación de Material Design. Scaffold proporciona espacios para TopAppBar, BottomBar, FloatingActionButton, Drawer y Snackbar. Según Google Android Documentation, 2025, Scaffold es un elemento obligatorio en la mayoría de las pantallas en aplicaciones con Compose, ya que gestiona los márgenes para los componentes del sistema Material Design.
Puntos clave
Scaffold es una función composable que implementa el esqueleto de pantalla según la especificación de Material Design. Scaffold no es un contenedor en el sentido tradicional — es un gestor de diseño que coordina la colocación de varios componentes estándar de Material en la pantalla.
Scaffold gestiona los márgenes para TopAppBar, BottomBar y FloatingActionButton, así como los elementos del sistema — la barra de estado y la barra de navegación. Esto garantiza que el contenido no se superponga con los elementos del sistema y cumpla con las pautas de Material Design.
Según Material Design Guidelines, 2025, Scaffold debe ser el elemento raíz de cada pantalla de la aplicación. Reemplaza el obsoleto CoordinatorLayout del sistema View y proporciona una API más simple y declarativa para construir diseños de pantalla.
Scaffold acepta los parámetros modifier, scaffoldState, topBar, bottomBar, floatingActionButton, drawerContent, snackbarHost y content. El parámetro content recibe PaddingValues — los márgenes que el contenido principal debe considerar.
@Composable
fun BasicScaffold() {
Scaffold(
topBar = {
TopAppBar(
title = { Text("Inicio") }
)
},
floatingActionButton = {
FloatingActionButton(onClick = {}) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding)
) {
Text("Contenido principal")
}
}
}
topBar es el espacio para colocar la barra superior de la aplicación, generalmente TopAppBar o LargeTopAppBar. Scaffold añade automáticamente márgenes a innerPadding para que el contenido no se superponga con topBar. TopAppBar puede contener un título, un icono de navegación y acciones.
bottomBar es el espacio para la barra de navegación inferior. Soporta BottomNavigation, BottomAppBar o NavigationBar. Scaffold tiene en cuenta la altura de bottomBar al calcular innerPadding para el contenido. Según Material Design Guidelines, 2025, bottomBar debe utilizarse en pantallas con 3–5 puntos de navegación.
floatingActionButton es el espacio para el botón de acción flotante. Scaffold posiciona automáticamente el FAB según la especificación de Material Design — en la esquina inferior derecha con el margen correcto. floatingActionButtonPosition permite mover el FAB al centro del borde inferior de la pantalla.
En este ejemplo, Scaffold utiliza todos los espacios principales: TopAppBar con un título, BottomBar con tres elementos de navegación y FloatingActionButton para la acción principal.
@Composable
fun FullScaffold() {
Scaffold(
topBar = {
TopAppBar(
title = { Text("App") },
navigationIcon = {
IconButton(onClick = {}) {
Icon(Icons.Default.Menu, "Menu")
}
}
)
},
bottomBar = {
NavigationBar {
NavigationBarItem(
icon = { Icon(Icons.Default.Home, "Inicio") },
label = { Text("Home") },
selected = true,
onClick = {}
)
NavigationBarItem(
icon = { Icon(Icons.Default.Search, "Buscar") },
label = { Text("Search") },
selected = false,
onClick = {}
)
}
},
floatingActionButton = {
FloatingActionButton(onClick = {}) {
Icon(Icons.Default.Add, "Add")
}
}
) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
Text("Contenido de pantalla")
}
}
}
ScaffoldState es el objeto de estado de Scaffold que combina DrawerState y SnackbarHostState. DrawerState gestiona la apertura y cierre del menú lateral, mientras que SnackbarHostState gestiona la visualización y ocultación del Snackbar. El estado se crea mediante rememberScaffoldState() y se pasa al parámetro scaffoldState.
DrawerState proporciona métodos open y close para el control programático del Drawer. El estado del Drawer puede ser abierto, cerrado o parcialmente abierto. drawerGesturesEnabled permite deshabilitar el gesto de deslizamiento para abrir el Drawer, dejando solo la apertura programática mediante un botón.
SnackbarHostState gestiona el Snackbar — notificaciones temporales en la parte inferior de la pantalla. El método showSnackbar muestra un Snackbar con un mensaje y una acción opcional. Según Material Design Guidelines, 2025, Snackbar debe usarse para mensajes breves sin información críticamente importante.
@Composable
fun ScaffoldWithDrawer() {
val scaffoldState = rememberScaffoldState()
val scope = rememberCoroutineScope()
Scaffold(
scaffoldState = scaffoldState,
topBar = {
TopAppBar(
title = { Text("Menú") },
navigationIcon = {
IconButton(onClick = {
scope.launch {
scaffoldState.drawerState.open()
}
}) {
Icon(Icons.Default.Menu, "Menu")
}
}
)
},
drawerContent = {
Column(modifier = Modifier.padding(16.dp)) {
Text("Elemento 1")
Text("Elemento 2")
}
}
) { innerPadding ->
Box(modifier = Modifier.padding(innerPadding)) {
Text("Contenido")
}
}
}
Un ejemplo completo de pantalla con Scaffold incluye TopAppBar, BottomNavigation, FloatingActionButton y Snackbar para mostrar notificaciones al presionar el FAB. ScaffoldState se pasa a todos los componentes para la coordinación del estado.
@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, "Inicio") },
label = { Text("Home") }, selected = true, onClick = {})
NavigationBarItem(icon = { Icon(Icons.Default.Settings, "Configuración") },
label = { Text("Settings") }, selected = false, onClick = {})
}
},
floatingActionButton = {
FloatingActionButton(onClick = {
scope.launch {
state.snackbarHostState.showSnackbar("Hecho")
}
}) {
Icon(Icons.Default.Add, "Add")
}
}
) { padding ->
Box(
modifier = Modifier.padding(padding).fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text("Bienvenido")
}
}
}
innerPadding son los PaddingValues que Scaffold pasa al bloque content. Contienen los márgenes necesarios para evitar que el contenido se superponga con statusBar, navigationBar, topBar y bottomBar. El uso de innerPadding es obligatorio para una visualización correcta en diferentes dispositivos.
Scaffold calcula automáticamente innerPadding basándose en los márgenes del sistema y la altura de los espacios instalados. En dispositivos con cámara tipo isla o recorte en la pantalla, Scaffold ajusta los márgenes para la barra de estado. En dispositivos antiguos con botones físicos, el margen inferior puede estar ausente.
Según Android Developers, 2024, innerPadding debe aplicarse al contenedor raíz del contenido mediante Modifier.padding(innerPadding). Si el contenido usa un contenedor desplazable, innerPadding se aplica mediante Modifier.consumeWindowInsets para el correcto funcionamiento del teclado y los gestos del sistema.
Preguntas frecuentes
Scaffold no es un contenedor sino un gestor de diseño que controla los espacios para TopAppBar, BottomBar, FAB, Drawer y Snackbar, y también maneja automáticamente los márgenes para los componentes del sistema. Column y Box solo posicionan elementos sin considerar Material Design.
Scaffold se recomienda para pantallas que usan componentes de Material Design. En pantallas simples sin TopAppBar, BottomBar o FAB, Scaffold no es obligatorio, pero proporciona márgenes correctos del sistema a través de innerPadding, lo que es útil incluso sin espacios.
Pase ScaffoldState al parámetro scaffoldState de Scaffold, luego llame a state.snackbarHostState.showSnackbar(“Mensaje”) dentro de una corrutina. Scaffold mostrará automáticamente el Snackbar en la parte inferior de la pantalla.
Sí, Scaffold crea un estado interno por defecto si no se pasa scaffoldState. Sin embargo, para controlar programáticamente Drawer y Snackbar, es necesario crear y pasar ScaffoldState mediante rememberScaffoldState().
Use el parámetro floatingActionButtonPosition de Scaffold. Por defecto, el FAB se encuentra en la parte inferior derecha (FabPosition.End). Establezca FabPosition.Center para colocar el FAB en el centro del borde inferior de la pantalla.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también