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

    praveen@codewithpk.com
CodeWithPK

🧩 Chapter 3 – Text, Image, Button & TextField Composables (and the Secret Sauce: State πŸ”)

  • Home
  • Android
  • Jetpack Compose
  • 🧩 Chapter 3 – Text, Image, Button & TextField Composables (and the Secret Sauce: State πŸ”)
Chapter 3 – Text, Image, Button
  • codewithpk@720
  • November 10, 2025
  • 5 Views

Welcome back to the Compose series on codewithpk.com πŸ‘‹

In the last chapter, we created our first Compose project and explored the structure.
Now it’s time to build real UI β€” text, images, buttons, and input fields β€” and understand the magic ingredient behind Compose: State.

This is the chapter where things actually start moving on screen.
Let’s go step by step.


πŸ“ 1. The Text Composable

The simplest composable in Jetpack Compose is Text().
It’s the Compose version of TextView, but way more powerful and customizable.

Here’s the basic syntax:

@Composable
fun TextExample() {
    Text(text = "Hello, Jetpack Compose!")
}

Now, let’s make it look less boring.

You can customize text with properties like fontSize, fontStyle, fontWeight, color, and textAlign.

Example:

@Preview(showBackground = true)
@Composable
fun StyledText() {
    Text(
        text = "Hello, CodeWithPK!",
        fontSize = 36.sp,
        fontStyle = FontStyle.Italic,
        fontWeight = FontWeight.ExtraBold,
        color = Color.Red,
        textAlign = TextAlign.Center
    )
}

πŸ’‘ Dev Trick:

  • Use sp (scale-independent pixels) for font size.
  • Use dp for dimensions (width, height, padding).
  • Always import colors from androidx.compose.ui.graphics.Color, not android.graphics.Color.

If you hold Ctrl + Click on the Text() composable in Android Studio, you’ll see all available properties β€” like maxLines, overflow, and fontFamily.


πŸ–ΌοΈ 2. The Image Composable

Next up β€” images.

In the XML world, we used ImageView.
In Compose, you’ll use the Image() composable.

Here’s a simple example using a drawable resource:

@Preview(showBackground = true)
@Composable
fun ImageExample() {
    Image(
        painter = painterResource(id = R.drawable.heart_icon),
        contentDescription = "Heart Icon ❀️"
    )
}

πŸ’‘ Key Properties You Should Know:

Property What it does
contentDescription Accessibility label for screen readers
colorFilter Tint or recolor the image
contentScale Defines how the image scales inside the layout (Crop, Fit, FillBounds)

Example with tint:

Image(
    painter = painterResource(R.drawable.heart_icon),
    contentDescription = "Blue Heart",
    colorFilter = ColorFilter.tint(Color.Blue),
    contentScale = ContentScale.Crop
)

πŸ’‘ Dev Trick:
Want to load an image from a URL?
Use Coil β€” a third-party image loader built for Compose.

implementation("io.coil-kt:coil-compose:2.6.0")

Example:

Image(
    painter = rememberAsyncImagePainter("https://example.com/photo.jpg"),
    contentDescription = "Remote Image"
)

πŸ”˜ 3. The Button Composable

Buttons in Compose are cleaner than the XML nightmares we used to deal with.

Example:

@Preview(showBackground = true)
@Composable
fun ButtonExample() {
    Button(
        onClick = { println("Button Clicked!") },
        colors = ButtonDefaults.buttonColors(
            containerColor = Color.Black,
            contentColor = Color.White
        ),
        enabled = true
    ) {
        Text("Click Me")
    }
}

πŸ’‘ Dev Trick:
You can place anything inside a Button β€” text, icons, even images.

Example:

Button(onClick = { /* TODO */ }) {
    Icon(Icons.Default.Favorite, contentDescription = "Like")
    Spacer(modifier = Modifier.width(8.dp))
    Text("Like")
}

You can also customize elevation, border, or shape:

Button(
    onClick = { /* Click */ },
    border = BorderStroke(2.dp, Color.Red),
    shape = RoundedCornerShape(12.dp)
) {
    Text("Rounded Button")
}

✏️ 4. TextField β€” Taking User Input

Now for one of the most important composables: TextField().

Think of it as the Compose version of EditText, but 100x easier to manage.

Basic usage:

@Preview(showBackground = true)
@Composable
fun TextFieldExample() {
    TextField(
        value = "Hello CodeWithPK",
        onValueChange = {},
        label = { Text("Your Name") },
        placeholder = { Text("Enter text here...") }
    )
}

Looks good, right?
But if you type something in the preview’s interactive mode, nothing happens.
Why?
Because we hardcoded the value.

We need state.


πŸ” 5. Understanding State in Jetpack Compose

Jetpack Compose is data-driven.
That means your UI reflects whatever state (data) you give it.

If the data changes, Compose automatically recomposes the affected UI β€” no notifyDataSetChanged(), no invalidateViews(), nothing.

Let’s fix our TextField to actually work.

@Preview(showBackground = true)
@Composable
fun TextFieldWithState() {
    var text by remember { mutableStateOf("") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Enter Something") },
        placeholder = { Text("Type here...") }
    )
}

Here’s what’s happening:

  • mutableStateOf("") creates a reactive variable.
  • remember ensures the state isn’t reset during recomposition.
  • When the user types, onValueChange updates the state.
  • Compose detects the change and redraws the UI automatically.

πŸ’‘ Dev Trick:
If you forget remember, the state resets every time Compose recomposes.
That’s the #1 reason your TextField won’t hold user input.


🧠 Behind the Scenes: Composition & Recomposition

When you run this example, Compose follows three steps:

  1. Initial Composition β€” It renders your UI for the first time using the current data.
  2. Event Handling β€” The user interacts with the app (e.g., types text or clicks a button).
  3. Recomposition β€” Compose re-calls your composable with the new data and updates only the changed parts.

Example Flow:

User types "A" β†’ state changes β†’ recomposition β†’ UI updates instantly

No manual UI updates, no lifecycle juggling.

πŸ’‘ Fun Fact: This reactive pattern is similar to how React, SwiftUI, and Flutter work β€” but Compose does it natively with Kotlin.


πŸ” 6. Bonus: Combine Composables

Because everything in Compose is modular, you can combine multiple composables together easily.

Example: a simple login card.

@Preview(showBackground = true)
@Composable
fun LoginCard() {
    var username by remember { mutableStateOf("") }
    var password by remember { mutableStateOf("") }

    Column(
        modifier = Modifier.padding(16.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        Text("Login", fontSize = 28.sp, fontWeight = FontWeight.Bold)
        TextField(value = username, onValueChange = { username = it }, label = { Text("Username") })
        TextField(value = password, onValueChange = { password = it }, label = { Text("Password") })
        Button(onClick = { println("Username: $username, Password: $password") }) {
            Text("Submit")
        }
    }
}

Congrats β€” you just built a fully functional form with no XML and no boilerplate.


🧩 Final Thoughts

In this chapter, you’ve learned:
βœ… How to use basic composables β€” Text, Image, Button, and TextField
βœ… How to style and customize them
βœ… How state drives UI and recomposition
βœ… And how to combine everything into interactive, dynamic layouts

The takeaway?

β€œIn Jetpack Compose, you don’t update the UI β€” you update the data, and the UI updates itself.” – codewithpk.com

Next up in Chapter 4, we’ll dive into Layouts and Modifiers β€” how to arrange composables beautifully using Row, Column, Box, and all those secret layout powers that make Compose addictive.


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

Share:

Previus Post
🧩 Chapter
Next 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