Devesh Rx Logo
Devesh Rx Blog

How to Build UI with Jetpack Compose: A Beginner's Guide (Part 7)

April 16, 2026

How to Build UI with Jetpack Compose: A Beginner's Guide (Part 7)

Building a high-performance user interface (UI) is the cornerstone of any successful Android application. For years, developers relied on XML layouts, but the industry has shifted. Enter Jetpack Compose—Android’s modern, declarative toolkit for building native UI.

Whether you are a beginner or a seasoned developer migrating from XML, this comprehensive Jetpack Compose tutorial will take you from the basic building blocks to creating a professional Material 3 card-based interface.

What is Jetpack Compose?

Jetpack Compose is a declarative UI toolkit. In the “old” imperative way (XML), you had to manually manage the state of the UI (e.g., findViewById and then calling setText).

In a declarative approach, you simply describe what the UI should look like for a given state. When the data changes, Compose automatically updates the UI. This process is known as Recomposition.

Jetpack Compose vs. Android XML: At a Glance

FeatureAndroid XML (Imperative)Jetpack Compose (Declarative)
LanguageXML + Java/Kotlin100% Kotlin
UI UpdatesManual (setText, setVisibility)Automatic (State-driven)
Code VolumeHigh (Separate layout and logic)Low (UI and logic in one place)
PreviewStatic PreviewInteractive/Live Previews

Understanding Composable Functions

The heart of Jetpack Compose is the @Composable function. These are special Kotlin functions that define a piece of your UI.

To create one, simply annotate your function with @Composable. These functions are the “building blocks” of your app; you can nest them within each other to create complex hierarchies.

import androidx.compose.material3.Text
import androidx.compose.runtime.Composable

@Composable
fun GreetingText(name: String) {
    // The Text component is a built-in Composable
    Text(text = "Hello $name! Welcome to Jetpack Compose.")
}

Code Breakdown:

  • @Composable: Tells the Kotlin compiler that this function is intended to convert data into UI.
  • Text(): A predefined Composable from the Material 3 library used to display text on the screen.

Mastering Jetpack Compose Layouts

In XML, you used LinearLayout or ConstraintLayout. In Compose, you use a few powerful layout components to arrange your elements.

1. Column (Vertical Stacking)

The Column layout stacks elements on top of each other.

@Composable
fun VerticalLayoutExample() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text("Item 1")
        Text("Item 2")
        Text("Item 3")
    }
}

2. Row (Horizontal Stacking)

The Row layout places elements side-by-side.

@Composable
fun HorizontalLayoutExample() {
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.SpaceBetween
    ) {
        Text("Left Side")
        Text("Right Side")
    }
}

3. Box (Overlapping Elements)

The Box layout allows you to stack elements on top of each other (Z-axis).

@Composable
fun OverlayExample() {
    Box(contentAlignment = Alignment.Center) {
        Image(painter = painterResource(id = R.drawable.bg_image), contentDescription = "Background")
        Text("Text Over Image", color = Color.White)
    }
}

4. Lazy Layouts (Scrollable Content)

For lists with hundreds of items, Column is inefficient because it renders everything at once. Instead, use Lazy Layouts, which only render items currently visible on the screen.

@Composable
fun FruitListExample() {
    val fruits = listOf("Apple", "Banana", "Cherry", "Date", "Elderberry")

    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(fruits) { fruit ->
            Text(
                text = "Fruit: $fruit", 
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

Essential UI Components in Material Design 3

By mastering these three core components, you can build almost any interface.

The Text Component

Text(
    text = "Hello World",
    fontSize = 20.sp,
    fontWeight = FontWeight.Bold,
    color = Color.Blue
)

The Image Component

Image(
    painter = painterResource(id = R.drawable.my_android_logo),
    contentDescription = "Android Logo", // Essential for accessibility
    modifier = Modifier.size(64.dp)
)

The Button Component

Button(onClick = { println("Button Clicked!") }) {
    Text(text = "Click Me")
}

Pro Tip: The Power of Modifiers

If Composable functions are the “what,” Modifiers are the “how.” Modifiers allow you to adjust the appearance and behavior of a component.

Text(
    text = "Styled Text",
    modifier = Modifier
        .padding(16.dp)                // Adds space around the element
        .background(Color.LightGray)   // Sets background color
        .fillMaxWidth()                // Makes element take full screen width
        .clickable { /* Handle click */ } // Makes element interactive
)

Project: Building a Material 3 Card List

Let’s combine everything into a professional, scrollable list of cards.

1. The Data Model

First, define a data class to hold your card information.

data class CardItem(
    val title: String, 
    val summary: String, 
    val imageRes: Int
)

2. The Individual Card UI

We will nest a Row (for image and text) and a Column (for title and summary) inside a Material 3 Card.

@Composable
fun ListItem(item: CardItem) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(8.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Row(modifier = Modifier.padding(16.dp)) {
            Image(
                painter = painterResource(id = item.imageRes),
                contentDescription = null,
                modifier = Modifier.size(60.dp)
            )
            Spacer(modifier = Modifier.width(16.dp))
            Column {
                Text(text = item.title, fontWeight = FontWeight.Bold, fontSize = 18.sp)
                Text(text = item.summary, fontSize = 14.sp)
                Button(onClick = { /* Action here */ }) {
                    Text("Read More")
                }
            }
        }
    }
}

3. The Main Screen (Scaffold & Surface)

Finally, we wrap everything in a Scaffold to ensure the UI doesn’t overlap with the system status bar.

@Composable
fun MainScreen() {
    val sampleData = listOf(
        CardItem("Jetpack Compose", "The modern way to build UI", R.drawable.compose_img),
        CardItem("Kotlin Multiplatform", "Share code across iOS and Android", R.drawable.kmp_img),
        CardItem("Material 3", "Latest design system by Google", R.drawable.m3_img)
    )

    Scaffold(
        topBar = {
            Text(
                text = "My Learning App", 
                modifier = Modifier.padding(16.dp), 
                style = MaterialTheme.typography.headlineMedium
            )
        }
    ) { paddingValues ->
        Surface(modifier = Modifier.padding(paddingValues)) {
            LazyColumn {
                items(sampleData) { item ->
                    ListItem(item)
                }
            }
        }
    }
}

FAQ: Common Jetpack Compose Questions

Q: Is Jetpack Compose replacing XML entirely? A: For new projects, yes. Google recommends Compose for all new Android development. However, Compose is interoperable, meaning you can use Compose views inside XML layouts and vice versa.

Q: What is the difference between Column and LazyColumn? A: A Column renders all its children at once. A LazyColumn only renders the items currently visible on the screen, making it essential for performance in long lists.

Q: What is a “Recomposition” in Compose? A: Recomposition is the process where Compose calls your Composable functions again with new data to update the UI. It only updates the parts of the UI that actually changed.

Q: How do I handle clicks in Jetpack Compose? A: You can use the onClick parameter in a Button or add a .clickable { } modifier to any other component like a Box or Text.


📌 Full Course Playlist https://www.youtube.com/playlist?list=PLO1OrQEU0vHNmD9Xqzs-qXwzzwrDvdhVu

#Tutorial
0 Introduction
1 Setting up Android Studio IDE
2 Mastering Android Studio: Navigating the IDE & Project Structure
3 Android Activity & Lifecycle Explained
4 Android Services: Background, Foreground, and Bound Services Explained
5 Android Broadcast Receivers: The Complete Guide to Listening and Sending Events
6 Android Content Provider API Tutorial: Access User Data Safely (Kotlin)
7 How to Build UI with Jetpack Compose: A Beginner’s Guide

~ ~ THANK YOU FOR READING ~ ~

Share: