Jetpack Compose Basics

Declarative UI

In Jetpack Compose the UI is a Kotlin function annotated with @Composable. You describe what the screen looks like for the current state; when the state changes, Compose calls the function again (recomposition) and updates only what changed. No XML layouts, no findViewById.

ComposeOld View system
TextTextView
Button, OutlinedButtonButton
TextField / OutlinedTextFieldEditText
Column / Row / BoxLinearLayout / FrameLayout
LazyColumnRecyclerView
Modifierlayout params, padding, click listeners

A Material 3 Card

@Composable
fun ProductCard(product: Product, onAdd: () -> Unit, modifier: Modifier = Modifier) {
    Card(
        modifier = modifier.fillMaxWidth(),
        elevation = CardDefaults.cardElevation(defaultElevation = 2.dp),
    ) {
        Row(
            modifier = Modifier.padding(16.dp),
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Column(modifier = Modifier.weight(1f)) {
                Text(product.name, style = MaterialTheme.typography.titleMedium)
                Text(
                    "₹${product.price}",
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.primary,
                )
            }
            FilledTonalButton(onClick = onAdd) { Text("Add") }
        }
    }
}

@Preview(showBackground = true)
@Composable
private fun ProductCardPreview() {
    MyShopTheme { ProductCard(Product(1, "Basmati Rice 5kg", 649), onAdd = {}) }
}

Rules for Composables

  • Name them like classes (ProductCard), return Unit, and accept a modifier: Modifier = Modifier parameter.
  • They must be fast and free of side effects: they can run many times. Do network/database work in the ViewModel, or in LaunchedEffect.
  • Pass state down and events up as lambdas (onAdd: () -> Unit). This is called state hoisting and makes composables reusable and previewable.