Jetpack Compose
01 / 02

Composables, State & Layout Basics

Composables, State & Layout Basics

Declarative UI

You describe WHAT the UI looks like for a given state; Compose figures out HOW to update it — the same paradigm shift as React (vs. jQuery) or SwiftUI (vs. UIKit), replacing imperative textView.setText(...) calls.

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

    Column(modifier = Modifier.padding(16.dp)) {
        Text("Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}

@Preview
@Composable
fun CounterPreview() {
    Counter()
}

remember{} keeps a value across recompositions (without it, state resets on every re-run). mutableStateOf() makes reading/writing trigger recomposition. The by delegate lets you use count directly instead of count.value. @Preview renders live in Android Studio, no build/deploy needed.

Layout Composables

Column { /* vertical, like LinearLayout(vertical) */ }
Row { /* horizontal */ }
Box { /* stacked, like FrameLayout */ }

Modifier
    .fillMaxWidth()
    .padding(16.dp)
    .background(Color.Blue)
    .clickable { onClick() }
// modifier order can affect the resulting layout

LazyColumn & Scaffold

LazyColumn only composes visible items (plus a small buffer) — Compose's RecyclerView equivalent for large/scrollable lists. Scaffold provides standard slots (top app bar, FAB, bottom nav, content) so they compose correctly without manual padding math.

ViewModel for Surviving Configuration Changes

Plain remember state doesn't survive an Activity recreation (like screen rotation) by default — a ViewModel holds state/logic scoped to the right lifecycle instead, separate from Composable functions which can be recreated more often.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free