Arrange UI with Column, Row, and Box, and shape every composable with modifiers — the chainable system that controls size, padding, background, and click behavior. Plus Scaffold for standard screen structure.
Three layout composables cover most arrangements: Column stacks children vertically, Row places them horizontally, and Box overlaps them (for backgrounds, badges). You control alignment and spacing with their arrangement and alignment parameters. Nesting these three is how you build essentially any screen layout in Compose.
@Composable
fun ProfileHeader() {
Column( // vertical stack
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(8.dp) // gap between children
) {
Text("Ada Lovelace", style = MaterialTheme.typography.titleLarge)
Row(horizontalArrangement = Arrangement.spacedBy(16.dp)) { // horizontal
Text("Following: 120")
Text("Followers: 8k")
}
}
// Box { } would OVERLAP children (e.g. an avatar with a badge on top).
}A Modifier is a chainable object that decorates a composable — size, padding, background, border, click handling, and much more. Nearly every composable takes a modifier parameter, and you build up appearance and behavior by chaining modifier calls. Crucially, order matters: padding before background differs from padding after it, because each modifier wraps the next.
@Composable
fun Badge(text: String) {
Text(
text = text,
modifier = Modifier
.padding(8.dp) // outer spacing
.background(Color.Blue, RoundedCornerShape(4.dp))
.padding(horizontal = 12.dp, vertical = 6.dp) // inner spacing
.clickable { /* handle tap */ },
color = Color.White
)
}
// ORDER MATTERS: padding BEFORE background = margin outside the color;
// padding AFTER background = padding inside the color. Each modifier wraps the next.Modifiers control size: fillMaxWidth/fillMaxSize expand to available space, size/width/height set fixed dimensions, and inside a Row or Column, weight distributes remaining space proportionally. Weight is how you build responsive layouts — two columns that split the screen 1:2, a spacer that pushes content apart — without hardcoding pixel values.
@Composable
fun Toolbar() {
Row(modifier = Modifier.fillMaxWidth()) {
Text("Title", modifier = Modifier.weight(1f)) // takes the leftover space
Icon(Icons.Default.Search, contentDescription = "Search")
Icon(Icons.Default.MoreVert, contentDescription = "More")
}
// weight(1f) on the title pushes the icons to the right edge.
}
@Composable
fun SplitPane() {
Row(Modifier.fillMaxSize()) {
Box(Modifier.weight(1f).fillMaxHeight()) // 1/3 of the width
Box(Modifier.weight(2f).fillMaxHeight()) // 2/3 of the width
}
}Scaffold provides the skeleton of a typical Material screen — slots for a top app bar, bottom bar, floating action button, and the main content — handling their placement and insets for you. Building screens inside a Scaffold gives you consistent, platform-correct structure without manually positioning system UI elements.
@Composable
fun HomeScreen() {
Scaffold(
topBar = { TopAppBar(title = { Text("Home") }) },
floatingActionButton = {
FloatingActionButton(onClick = { /* add */ }) {
Icon(Icons.Default.Add, contentDescription = "Add")
}
}
) { innerPadding ->
// main content — apply innerPadding so it doesn't hide under the bars
Column(modifier = Modifier.padding(innerPadding)) {
Text("Welcome!")
}
}
}
// Scaffold places the bars + FAB correctly and gives you padding for the content.