CodeWithPKCodeWithPK
CodeWithPK
  • Home
  • Blog
  • About
  • Services
  • Portfolio
  • Contact
  • Contact Us?

    praveen@codewithpk.com
CodeWithPK

🧩 Chapter 4 – Layouts in Jetpack Compose: Row, Column, Box, Arrangement & Lists

  • Home
  • Android
  • Jetpack Compose
  • 🧩 Chapter 4 – Layouts in Jetpack Compose: Row, Column, Box, Arrangement & Lists
Layouts in Jetpack Compose
  • codewithpk@720
  • November 11, 2025
  • 5 Views

Layouts are the building blocks of any UI using Layouts in Jetpack Compose. In the old View system we had LinearLayout, RelativeLayout, ConstraintLayout. In Compose we have Column, Row, and Box as the core primitives β€” and they solve 90% of everyday layout needs. This chapter explains them with simple examples and real-world patterns (list item, avatar + text row, overlapping images), plus tips you’ll actually use.


πŸ”Ή The mental model (quick)

  • Column = vertical stacking (one below another). Like a vertical LinearLayout.
  • Row = horizontal stacking (one next to another). Like a horizontal LinearLayout.
  • Box = z-stack / frame β€” children overlap; useful for badges, overlays, stacking.
  • LazyColumn / LazyRow = recyclable list (like RecyclerView). Use these for long lists.

Two important concepts:

  • Arrangement controls how extra space is distributed among children along the main axis.
  • Alignment controls how children are positioned on the cross axis.

Remember this:
Column’s main axis = vertical; cross axis = horizontal.
Row’s main axis = horizontal; cross axis = vertical.


βœ… Example 1 β€” Column (vertical list) with Arrangement & Alignment

@Preview(showBackground = true)
@Composable
fun ColumnExample() {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .height(200.dp)
            .padding(16.dp),
        verticalArrangement = Arrangement.SpaceEvenly, // distributes vertical space evenly
        horizontalAlignment = Alignment.CenterHorizontally // horizontal center
    ) {
        Text("Item A", fontSize = 20.sp)
        Text("Item B", fontSize = 18.sp)
        Text("Item C", fontSize = 16.sp)
    }
}

Key points:

  • Arrangement.SpaceEvenly places equal space before/after/between children.
  • horizontalAlignment = Alignment.Start/CenterHorizontally/End controls cross-axis alignment.

Other useful Arrangements:

  • SpaceBetween β€” max space between items, none at ends.
  • Top, Bottom, Center (or Top, CenterVertically etc depending on context).

βœ… Example 2 β€” Row (horizontal) with weight and spacing

Common scenario: icon + text + trailing timestamp. Use weight for flexible widths.

@Composable
fun RowItemExample() {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(12.dp),
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.Start
    ) {
        Image(
            painter = painterResource(R.drawable.ic_avatar),
            contentDescription = "avatar",
            modifier = Modifier.size(48.dp)
        )

        Spacer(modifier = Modifier.width(12.dp))

        Column(modifier = Modifier.weight(1f)) {
            Text("Title", fontWeight = FontWeight.Bold)
            Text("Subtitle or small description", fontSize = 12.sp, color = Color.Gray)
        }

        Text("2h", fontSize = 12.sp, color = Color.Gray) // trailing
    }
}

Tips:

  • Put the flexible content in .weight(1f) so trailing elements stay snug to the end.
  • Spacer is your friend for fixed gaps.

βœ… Example 3 β€” Box: overlays, badges, backgrounds

Box stacks children; first child drawn below, next on top.

@Preview(showBackground = true)
@Composable
fun BoxBadgeExample() {
    Box(modifier = Modifier.size(120.dp)) {
        Image(
            painter = painterResource(R.drawable.sample_cover),
            contentDescription = "cover",
            modifier = Modifier.fillMaxSize(),
            contentScale = ContentScale.Crop
        )

        // A small badge at top-right
        Box(
            modifier = Modifier
                .align(Alignment.TopEnd)
                .padding(8.dp)
                .background(Color.Black.copy(alpha = 0.6f), shape = CircleShape)
                .padding(horizontal = 8.dp, vertical = 4.dp)
        ) {
            Text("NEW", color = Color.White, fontSize = 12.sp)
        }
    }
}

Use align(Alignment.X) on child to place it inside the Box.


βœ… Example 4 β€” Creating a List Item (image + texts) and rendering it many times

Here’s a typical list item: avatar/image left, column of texts right. Then render with a LazyColumn.

data class Device(val imageRes: Int, val name: String, val info: String)

@Composable
fun DeviceListItem(device: Device) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(12.dp),
        verticalAlignment = Alignment.CenterVertically
    ) {
        Image(
            painter = painterResource(device.imageRes),
            contentDescription = null,
            modifier = Modifier.size(56.dp).clip(RoundedCornerShape(8.dp)),
            contentScale = ContentScale.Crop
        )

        Spacer(modifier = Modifier.width(12.dp))

        Column(modifier = Modifier.weight(1f)) {
            Text(device.name, fontWeight = FontWeight.Bold)
            Text(device.info, fontSize = 12.sp, color = Color.Gray)
        }

        IconButton(onClick = { /* action */ }) {
            Icon(Icons.Default.MoreVert, contentDescription = "menu")
        }
    }
}

@Preview(showBackground = true)
@Composable
fun DeviceListPreview() {
    val items = List(10) { i ->
        Device(R.drawable.sample_cover, "Device $i", "${8 + i} GB RAM")
    }
    LazyColumn {
        items(items) { device ->
            DeviceListItem(device)
            Divider()
        }
    }
}

Important:

  • LazyColumn is the Compose equivalent of RecyclerView β€” it lazily composes items, efficient for long lists.
  • Use items() or itemsIndexed() for lists.

βœ… Example 5 β€” Horizontal list (LazyRow)

@Preview(showBackground = true)
@Composable
fun HorizontalListPreview() {
    val images = List(8) { R.drawable.sample_cover }
    LazyRow(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.padding(12.dp)) {
        items(images) { img ->
            Image(
                painter = painterResource(img),
                contentDescription = null,
                modifier = Modifier.size(140.dp).clip(RoundedCornerShape(10.dp)),
                contentScale = ContentScale.Crop
            )
        }
    }
}

πŸ”§ Modifier basics you’ll use every day

Modifier is the glue. Common ones:

  • .fillMaxWidth(), .fillMaxSize()
  • .wrapContentHeight(), .height(200.dp), .width(48.dp)
  • .padding(12.dp), .offset(x=..., y=...)
  • .size(40.dp) β€” convenience for both width+height
  • .clip(RoundedCornerShape(...)) β€” for rounded corners
  • .background(Color, shape) β€” gives background color and shape
  • .weight(1f) β€” used inside Row/Column to take proportional space
  • .clickable { } β€” for clickable behavior

Example: Modifier.weight(1f).padding(8.dp) β€” flexible plus spacing.


🧠 Common gotchas & developer tricks

  1. Use weight for flexible content
    When a Row has a trailing fixed element (button, icon), use .weight(1f) on the center column to push trailing content to the end.
  2. Prefer Lazy lists for long content
    Column with .verticalScroll() composes everything β€” bad for large lists. Use LazyColumn so items are recycled.
  3. Use Arrangement vs Alignment intentionally
    Arrangement = how leftover main-axis space is distributed. Alignment = cross-axis positioning. Confusing them causes odd layout results.
  4. Modifier order matters
    Modifier.padding().clickable() behaves differently than Modifier.clickable().padding() in some edge cases (padding influences clickable area). Usually put clickable at end when you want padding included in touch target.
  5. Box for overlays
    Want badge, gradient overlay, or text over image? Use Box and align(...) for children.
  6. Performance
    Keep composables small and stateless where possible. If a composable does heavy work, move that to a ViewModel or remember-derived-state to avoid expensive recompositions.
  7. Preview multiple sizes
    Use multiple @Preview annotations to test different screen sizes and dark/light themes.

πŸ“¦ Example: Combining everything β€” a small catalog card list

@Composable
fun CatalogCard(item: Device) {
    Card(
        modifier = Modifier
            .padding(8.dp)
            .fillMaxWidth(),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Row(modifier = Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically) {
            Image(painter = painterResource(item.imageRes),
                  contentDescription = null,
                  modifier = Modifier.size(64.dp).clip(RoundedCornerShape(8.dp)),
                  contentScale = ContentScale.Crop)

            Spacer(modifier = Modifier.width(12.dp))

            Column(modifier = Modifier.weight(1f)) {
                Text(item.name, fontWeight = FontWeight.Bold)
                Text(item.info, fontSize = 12.sp, color = Color.Gray)
            }

            Button(onClick = { /* buy */ }) {
                Text("Buy")
            }
        }
    }
}

@Composable
fun CatalogList(items: List<Device>) {
    LazyColumn {
        items(items) { CatalogCard(it) }
    }
}

This pattern is what you’ll use for feeds, product lists, message lists β€” everything.


🧩 Final checklist before you ship a layout

  • Does the layout adapt to screen size and orientation? Test different devices.
  • Are touch targets at least 48dp? Buttons/icons should be tappable.
  • Does the list use LazyColumn for many items? If not, switch.
  • Do you use remember for expensive computations used in composables?
  • Have you added content descriptions for images for accessibility? (contentDescription)

πŸ”œ What’s next (Chapter 5 preview)

In the next chapter we’ll deep-dive into Modifiers & Custom Layouts: how to create your own layout composable, write performant modifiers, and build a responsive grid. You’ll also learn when to use Layout/SubcomposeLayout for advanced scenarios.


Made with ❀️ by codewithpk.com
Keep building. Keep learning. Keep shipping.

Tags:

Android UI Column Row Box Compose 2025 Compose Layouts Compose Modifiers Compose tutorial Jetpack Compose Kotlin UI LazyColumn

Share:

Previus Post
🧩 Chapter

Leave a comment

Cancel reply

Recent Posts

  • 🧩 Chapter 4 – Layouts in Jetpack Compose: Row, Column, Box, Arrangement & Lists
  • 🧩 Chapter 3 – Text, Image, Button & TextField Composables (and the Secret Sauce: State πŸ”)
  • 🧩 Chapter 2 – Setting Up Jetpack Compose (From Zero to Running App) πŸš€
  • 🧩 Chapter 1 – What is Jetpack Compose? (The Cleanest Explanation You’ll Ever Need)
  • Massive News for Android Developers Regarding Play Store! πŸš€

Recent Comments

  1. 🧩 Chapter 1 – What is Jetpack Compose? (The Cleanest Explanation You’ll Ever Need) – CodeWithPK on 🧩 Chapter 2 – Setting Up Jetpack Compose (From Zero to Running App) πŸš€
  2. Aanand on Future of Native Android Development: Trends, Insights, and Opportunities πŸš€

Recent Post

  • Layouts in Jetpack Compose
    11 November, 2025🧩 Chapter 4 – Layouts in
  • Chapter 3 – Text, Image, Button
    10 November, 2025🧩 Chapter 3 – Text, Image,
  • Jetpack Compose Setup
    08 November, 2025🧩 Chapter 2 – Setting Up

category list

  • Android (25)
  • Blog (35)
  • Business News (6)
  • Jetpack Compose (3)
  • Programming (6)
  • Technology (5)

tags

AI Android architecture Android best practices android developer guide Android developer tips Android Development Android interview preparation android interview questions Android performance optimization Android testing Android Tips Async Code Simplified Asynchronous Programming business news Clean Code Code Optimization Code Quality Coding Tips And Tricks Compose tutorial Coroutines Basics data structures and algorithms dependency injection Dirty Code Efficient Code electric vehicles Error Handling In Coroutines Jetpack Compose Jetpack Integration Kotlin Kotlin Coroutines Kotlin For Beginners Kotlin Multiplatform Kotlin Tips Kotlin Tutorial Kotlin Tutorials Kotlin UI Learn Kotlin Mobile App Development Multithreading Simplified Programming Made Easy RBI updates startup updates Structured Concurrency technology news UI Thread Management

Copyright 2025 codewithpk.com All Rights Reserved by codewithpk.com