DEV Community

Cover image for Compose Beginners 2: The Lego Bricks of Android UI
Abizer
Abizer

Posted on

Compose Beginners 2: The Lego Bricks of Android UI

In Blog 1 you discovered why Jetpack Compose transformed Android UI development, moving from mutation-heavy XML to a state-driven, declarative paradigm. Now in Blog 2, we’ll step into the how: what exactly is a @Composable, how to think of it as building Lego bricks for your UI, and how to start building your own interactive UI piece (no XML involved).


1. Revisiting the Paradigm Shift

In the first blog you explored how Compose makes UI a function of state rather than a set of mutable views.
Let’s carry that mindset forward:

Instead of “how do I update the view”, we ask “what should the UI look like given this state?”

Instead of XML inflation and findViewById(), we get declarative functions.

Instead of manually tracking UI changes, Compose’s runtime handles recomposition for us.

In short: we’ve already embraced the why. Now we’ll embrace the what and how of the building blocks.


2. Composables = The Lego Bricks

Imagine you’re building a model with Lego bricks. Each brick is simple; you just snap them together. Similarly, a @Composable function is a building-block for your UI.

@Composable
fun Greeting() {
    Text(text = "Hello!")
}
Enter fullscreen mode Exit fullscreen mode

Pretty basic but imagine combining many such composables (bricks) to build your screen. That’s the Compose way.

Why this analogy helps

  • Reusable: Just like bricks can be used in different models, composables can be reused.

  • Composable: You stack them or nest them (Column, Row, Box) to build screens.

  • State-driven: When the underlying state changes, only the bricks depending on it are “re-snapped” (recomposed), not everything collapses.


3. What Makes a Function “Composable”

Let’s define it clearly:

  • A function annotated with @Composable.

  • Takes UI inputs (parameters) and draws UI.

  • Doesn’t return a view — instead it describes part of the UI tree.

  • Can call other composables.

  • Works hand-in-hand with Compose runtime for efficient recomposition.

@Composable
fun MyButton(onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("Tap Me")
    }
}
Enter fullscreen mode Exit fullscreen mode

This is your brick: self-contained, parameterised, reusable.


✅ Fact-Check Note

As of Compose BOM 2025.09.00 (and Kotlin 2.0+), the Compose compiler transforms composables and the runtime handles composition and recomposition.
Always refer to the official docs.


4. Build Your First Interactive Brick (A Counter)

Let’s put all this into action. You don’t need a demo video; you’ll implement and preview with Android Studio’s Preview.

@Composable
fun CounterDemo() {
    var count by remember { mutableStateOf(0) }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "Count: $count",
            style = MaterialTheme.typography.headlineMedium
        )
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { count++ }) {
            Text("Add One")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Here’s what you’ll notice:

count is state.

When the button is clicked, state changes → Compose recomposes the part of UI displaying the count.

You didn’t deal with findViewById, Adapter.notifyDataSetChanged(), or manual UI updates.

A small twist to add delight

You may swap the static text with a changing emoji:

val emoji = listOf("🌱", "🌿", "🌳", "🌲")
Text("${emoji[count % emoji.size]}  Count: $count")
Enter fullscreen mode Exit fullscreen mode

See how the UI reflects the state instantly? You’re building with bricks, not manipulating glue.


5. Why This Building Block Matters

Connecting back to Blog 1: you already understand that Compose changed how we think about UI. Now with composables you see how we build UI under that new thinking.

Predictability: UI = f(state). Your bricks visualize exactly that.

Reusability & Modularity: Each composable is a brick you can reuse across screens, which is much easier than large XML layouts with tangled dependencies.

Performance: Since only affected bricks recompute, you get efficient UI updates without manual optimisation.


🧠 Reader Takeaway

You now know what composables are, why they matter, and how to start building UI with them. In the first post you grasped why Compose changed Android. In this post, you’ve begun to grasp how, turning that paradigm into your first bricks.

Top comments (0)