Compose Layouts, Modifiers, Padding & ConstraintLayout

In Jetpack Compose, layout composition is clean and intuitive. You do not write deeply nested XML files with multiple passes of layout_weight recalculations. Instead, you compose lightweight layout containers using Arrangements, Alignments, and Modifiers.

Arrangement vs. Alignment in Rows & Columns

Every Row and Column layout container accepts two key spatial parameters:

  • Arrangement (Main Axis): Controls how children are distributed along the container's primary direction (vertical for Column, horizontal for Row). Values include Arrangement.SpaceBetween, SpaceEvenly, SpaceAround, Center, and spacedBy(8.dp).
  • Alignment (Cross Axis): Controls how children are aligned perpendicularly across the opposite axis (horizontal for Column, vertical for Row). Values include Alignment.CenterHorizontally, CenterVertically, Start, and End.
@Composable
fun ActionToolbar() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp, vertical = 8.dp),
        horizontalArrangement = Arrangement.SpaceBetween, // Main Axis
        verticalAlignment = Alignment.CenterVertically      // Cross Axis
    ) {
        Text("Dashboard", style = MaterialTheme.typography.titleLarge)
        Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
            IconButton(onClick = { /* Search */ }) {
                Icon(Icons.Default.Search, contentDescription = "Search")
            }
            IconButton(onClick = { /* Settings */ }) {
                Icon(Icons.Default.Settings, contentDescription = "Settings")
            }
        }
    }
}

The Scaffold Layout: TopAppBar, BottomBar & FloatingActionButton

Modern Material Design applications follow standard screen scaffolds. Compose provides the Scaffold composable to structure your TopAppBar, Bottom Navigation bar, Floating Action Button, and SnackbarHost effortlessly:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreenScaffold() {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text("Veewom Android") },
                colors = TopAppBarDefaults.topAppBarColors(
                    containerColor = Color(0xFF00B0FF),
                    titleContentColor = Color.White
                )
            )
        },
        floatingActionButton = {
            FloatingActionButton(
                onClick = { /* Add item */ },
                containerColor = Color(0xFF00B0FF),
                contentColor = Color.White
            ) {
                Icon(Icons.Default.Add, contentDescription = "Add")
            }
        },
        bottomBar = {
            NavigationBar {
                NavigationBarItem(
                    selected = true,
                    onClick = { },
                    icon = { Icon(Icons.Default.Home, contentDescription = "Home") },
                    label = { Text("Home") }
                )
                NavigationBarItem(
                    selected = false,
                    onClick = { },
                    icon = { Icon(Icons.Default.Book, contentDescription = "Tutorials") },
                    label = { Text("Tutorials") }
                )
            }
        }
    ) { innerPadding ->
        // Content area respects system bars and app bar padding!
        Column(
            modifier = Modifier
                .fillMaxSize()
                .padding(innerPadding)
                .padding(16.dp)
        ) {
            Text("Welcome to the modern Scaffold layout!")
        }
    }
}

ConstraintLayout in Jetpack Compose

For complex UI relationships where elements depend on multiple dynamic siblings, you can use androidx.constraintlayout.compose:constraintlayout-compose:

@Composable
fun ConstraintProfileHeader() {
    ConstraintLayout(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
        val (avatar, nameText, bioText, followBtn) = createRefs()

        Image(
            painter = painterResource(id = R.drawable.ic_launcher_foreground),
            contentDescription = "Avatar",
            modifier = Modifier
                .size(72.dp)
                .constrainAs(avatar) {
                    top.linkTo(parent.top)
                    start.linkTo(parent.start)
                }
        )

        Text(
            text = "Android Masterclass",
            fontWeight = FontWeight.Bold,
            modifier = Modifier.constrainAs(nameText) {
                top.linkTo(avatar.top)
                start.linkTo(avatar.end, margin = 16.dp)
            }
        )

        Button(
            onClick = { },
            modifier = Modifier.constrainAs(followBtn) {
                top.linkTo(nameText.bottom, margin = 8.dp)
                start.linkTo(avatar.end, margin = 16.dp)
            }
        ) {
            Text("Enroll Now")
        }
    }
}

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. Why must I always use innerPadding provided by Scaffold?

The `innerPadding` parameter calculates the exact physical pixel height occupied by the TopAppBar, BottomBar, and system navigation bar. Failing to apply `Modifier.padding(innerPadding)` to your content container will cause your UI to be clipped or hidden behind the bars.

Q2. When should I choose ConstraintLayout over nested Rows and Columns?

Use standard Rows, Columns, and Boxes for 90% of layouts because they are simpler and compile faster. Use ConstraintLayout when you have complex cross-axis alignment requirements (e.g., aligning an element to the middle of two other elements) or complex animations between layout constraints.

Q3. How does Modifier.weight(1f) work in Compose?

`Modifier.weight(1f)` instructs a child inside a Row or Column to expand and fill the remaining available space along the main axis after all non-weighted siblings have been measured.

Explore Related Android Development Classes & Next Steps

Broaden your foundational and advanced Android application development skills across our curriculum:

Material Design 3 (M3)

Use Material 3 Scaffolds, TopAppBars, FloatingActionButtons, and Cards.

LazyColumn, Lists & Grids

Construct efficient recycling vertical and horizontal list layouts.

State Management in Compose

Update layouts dynamically in response to state mutations.

35+ Hands-On Practice Projects

Build real-world Compose layouts in our interactive project lab.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!