Jetpack Compose for Beginners · Lesson 1 of 9

Getting Started with Jetpack Compose

Your first step into modern Android UI: what Jetpack Compose is, how a composable function describes the screen, and how Text, Icon, Column, Preview and Modifier fit together into your first small screen.

Hello, Compose!

Imagine we want our Android phone to display a simple message:

Hello, Compose!

That's where we'll start. In this lesson we'll keep things deliberately small and friendly:

  • No MVVM.
  • No repositories.
  • No dependency injection.
  • No complicated Android architecture.

All of those have their place, and we'll get to the ones you need later in the course. For now, the only goal is to understand how Compose puts things on the screen. By the end of this lesson, you'll have built this:

        ★

   Hello, Compose!

 Build beautiful Android apps
The screen you'll build in this lesson: an icon, a title and a subtitle.

What Is Jetpack Compose?

Jetpack Compose is Android's modern toolkit for building user interfaces.

The user interface, or UI, is everything you see and touch in an app:

  • Text
  • Images
  • Buttons
  • Lists
  • Forms
  • Screens
  • Animations

For many years, Android UI was built in two separate places. You described the layout in an XML file, and then wrote Kotlin or Java code that found those views and changed them — setting text, hiding and showing things, reacting to taps.

Traditional Android
  layout.xml    → the layout
  Activity.kt   → updates the views

Jetpack Compose
  Kotlin        → describes the UI
Compose replaces the XML-plus-code split with UI written in Kotlin.

With Compose, you describe the UI directly in Kotlin:

Text("Hello, Compose!")

That single line says "show some text that reads Hello, Compose!". You don't create a view, look it up, and then set its text in a separate step. You simply describe what should appear, and Compose works out how to draw it. This style is called declarative UI: you declare what the screen should look like, rather than giving step-by-step instructions to change it.

If you've seen SwiftUI, Apple's UI framework for iOS, this might look familiar:

SwiftUI:   Text("Hello, SwiftUI!")
Compose:   Text("Hello, Compose!")
Both frameworks describe UI declaratively.

You don't need to know SwiftUI to follow this course — but if you're learning both, it helps to notice the ideas they share.

Note

To follow along, create a new project in Android Studio with the Empty Activity template, which uses Compose. Your code goes in MainActivity.kt, and the Split or Design view shows previews of your UI — you'll set one up later in this lesson.

Your First Composable

Here is a complete piece of Compose UI:

@Composable
fun Greeting() {
    Text("Hello, Compose!")
}

The line to notice is @Composable. It's an annotation — a label attached to the function — and it means:

Key idea

"This function can describe part of the user interface."

A function marked with @Composable is called a composable function, or just a composable. Greeting is a composable, and so is Text.

Composables come in every size. A whole screen can be a composable, and so can a tiny piece of one:

Whole screens         Smaller pieces
HomeScreen            ProfileCard
ProfileScreen         UserAvatar
SettingsScreen        FollowButton
LoginScreen           SearchBar
Screens and small components are all composable functions.

A ProfileScreen might contain a ProfileCard, which contains a UserAvatar and a FollowButton. Big pieces are made from smaller pieces.

Key idea

Compose apps are built by combining composable functions.

Just a Kotlin Function

Let's take a step back. Without the annotation and the text, Greeting is an ordinary Kotlin function — one that doesn't do anything yet:

fun Greeting() {
}

Now add @Composable and put a Text inside:

@Composable
fun Greeting() {
    Text("Hello, Compose!")
}

It's still a Kotlin function. @Composable changes its role: instead of being a function that only runs some code, it can now take part in describing the UI. That's all you need to know about it for now — there's no need to worry about what happens behind the scenes.

Showing Text

Text shows a piece of text on the screen. The simplest version takes just the words:

Text("Hello!")

Change the words, and the screen changes with them:

Text("I'm learning Jetpack Compose!")

Most of the time you'll want more than the words. You might want the text bigger, for example. To do that, we give Text more information by naming each piece:

Text(
    text = "I'm learning Jetpack Compose!",
    fontSize = 24.sp
)

text = says which words to show, and fontSize = 24.sp says how big they should be. We'll come back to what sp means shortly.

We can make it bold too:

Text(
    text = "I'm learning Jetpack Compose!",
    fontSize = 24.sp,
    fontWeight = FontWeight.Bold
)

Each named piece answers one question about the text. You can picture it like this:

Text
 │
 ├── What text?
 ├── What size?
 └── What weight?
text answers "what text?", fontSize answers "what size?", and fontWeight answers "what weight?".

You only include the ones you need. Leave out fontWeight, and the text uses the normal weight.

Showing an Icon

Our target screen has a star at the top. To show an icon, use Icon:

Icon(
    imageVector = Icons.Default.Star,
    contentDescription = "Star"
)

imageVector chooses which icon to draw — here, the built-in star. contentDescription is a short description of the icon. It's read aloud by screen readers such as TalkBack, so people who can't see the screen still know what's there.

Tip

Always give meaningful icons a contentDescription. It's a small habit that makes your apps usable by far more people.

Notice that Text and Icon are both composables. They're pieces of UI that you place inside your own composable functions. Compose has many more, which you'll meet as the course goes on — for example:

  • Button
  • Image
  • Card
  • TextField
  • Switch

You don't need to learn those yet. They all work on the same idea: a composable that describes a piece of UI.

Arranging with Column

Our target screen has three pieces:

Icon
Text
Text

They need to be arranged one above the other. For that, Compose gives us Column: a container that places its children vertically, from top to bottom.

Column {
    Icon(
        imageVector = Icons.Default.Star,
        contentDescription = "Star"
    )

    Text("Hello, Compose!")

    Text("Build beautiful Android apps")
}
Column
   │
   ├── Icon
   ├── Text
   └── Text
The Column holds its children and shows them top to bottom, in the order you write them.

If you've used SwiftUI, here's the one comparison worth making at this point:

SwiftUI        Compose

VStack    →    Column
Both arrange views vertically.

We'll introduce comparisons like this gradually, only when they genuinely help — not as a big table to memorise.

Spacing, dp and sp

By default, a Column places its children right against each other. To add space between them, tell the Column how to arrange its children:

verticalArrangement = Arrangement.spacedBy(16.dp)

Here's the complete example, with our title styled as well:

@Composable
fun Greeting() {
    Column(
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Icon(
            imageVector = Icons.Default.Star,
            contentDescription = "Star"
        )

        Text(
            text = "Hello, Compose!",
            fontSize = 24.sp,
            fontWeight = FontWeight.Bold
        )

        Text(
            text = "Build beautiful Android apps"
        )
    }
}

Now there are 16 units of space between each item. You've probably noticed two new little endings, dp and sp. For now, all you need is this:

16.dp  →  spacing
24.sp  →  text size
Use dp for sizes and spacing, and sp for text.

Both are Android's way of measuring things so they look right on phones with very different screens. You'll understand them properly later in the course; for this lesson, dp for spacing, sp for text is enough.

Tip

Android Studio usually adds the import lines for you — if a name shows up in red, click it and press Alt+Enter (Option+Enter on a Mac). For reference, this lesson uses:

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Star
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

If Icons can't be found in a newer project, add the Material icons library to your app's dependencies: implementation("androidx.compose.material:material-icons-core").

Seeing It with Preview

You don't have to run the app on a phone every time you change something. Android Studio can show a preview of a composable right next to your code. To get one, write a small composable marked with @Preview:

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    Greeting()
}

GreetingPreview simply shows Greeting, and showBackground = true gives it a plain background so it's easy to see. Open the Split view in Android Studio and your screen appears beside the code, updating as you work.

Notice what just happened: one composable (GreetingPreview) used another (Greeting). That's exactly how larger UI is built. A home screen, for example, might be put together like this:

HomeScreen
   │
   ├── Header
   ├── WelcomeCard
   ├── RecentItems
   └── BottomSection
Larger UI is built from smaller composables.

Modifier

So far we've changed what a composable shows. But what about the space around it, or how wide it is? For that, Compose has Modifier:

Text(
    text = "Hello, Compose!",
    modifier = Modifier.padding(16.dp)
)

Modifier.padding(16.dp) adds 16 units of space around the text. Padding is only one of many things a modifier can control. Modifiers can affect:

  • padding
  • size
  • background
  • click behavior
  • alignment
  • borders

You can also chain several modifiers together, one after another:

Modifier
    .padding(16.dp)
    .fillMaxWidth()

This adds padding and lets the composable fill the full width available. You'll use modifier chains in almost every screen you build, and Lesson 2 explores them further.

Key idea

Modifier changes how a composable looks, behaves, or is laid out.

Lesson Recap

Here's everything from this lesson in one picture:

@Composable
    ↓
Composable function

Text / Icon
    ↓
UI pieces

Column
    ↓
arranges UI

Modifier
    ↓
changes layout / appearance / behavior

And the big idea behind all of it:

Screen
  │
  ├── Composable
  ├── Composable
  └── Composable
Every screen is made of composables.
What you learned
  • @Composable turns a Kotlin function into a composable function that describes part of the UI.
  • Text and Icon are UI pieces.
  • Column arranges UI from top to bottom.
  • Modifier changes layout, appearance and behavior.
  • Screens are built by combining composables.

You don't need to memorise every API from this lesson. What matters is the idea: small composables, combined into bigger ones, describe the whole screen.

Tiny Challenge

Your turn

Create a new composable that shows this:

        ♥️

       Welcome!

 I'm learning Jetpack Compose

Use:

  • Column
  • Icon (hint: look for a heart in Icons.Default)
  • Text
  • fontSize
  • FontWeight

Don't worry about centering everything perfectly or making it look polished yet — that's what Lesson 2 is for. The goal here is composition: building your screen from composables inside composables.

Composable
     ↓
Composable
     ↓
Composable

Coming Up in Lesson 2

In Lesson 2 — Building Your First Screen, you'll meet the tools for real layouts:

Column · Row · Box · Spacer

Modifier
  padding · size
  fillMaxWidth · background

Alignment · Arrangement · Colors

But we won't study them as a list of disconnected APIs. Lesson 2 uses them together to build one complete, attractive Android screen — following the same rhythm as this lesson:

Explain → visualize → code
  → experiment → build → challenge