LAYERS

Runtime Layer

  • Core primitives: @Composable, remember, SideEffect, mutableStateOf
  • Handles state management and recomposition
  • No UI rendering

Example:

@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    SideEffect {
        println("Count changed to: $count")
    }
    // UI rendering happens in higher layers
}

UI Layer

  • Layout measurement (LayoutNode)
  • Drawing capabilities (DrawScope)
  • Modifiers system
  • Input handling
  • Text rendering

Example:

@Composable
fun CustomBox() {
    Box(
        modifier = Modifier
            .size(100.dp)
            .pointerInput(Unit) {
                detectTapGestures { offset ->
                    // Handle touch input
                }
            }
    ) {
        // Custom drawing and layout
    }
}

Foundation Layer

  • Basic UI structures: Row, Column, Box, LazyColumn
  • Gesture support
  • Design-system agnostic
  • Building blocks for custom designs

Example:

@Composable
fun CustomLayout() {
    Column(
        modifier = Modifier.fillMaxWidth(),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Box(
            modifier = Modifier
                .size(200.dp)
                .pointerInput(Unit) {
                    detectDragGestures { change, dragAmount ->
                        // Handle drag gesture
                    }
                }
        )
    }
}

Material Layer

  • Material Design implementation
  • Theming and typography
  • Ready-made components: Button, TextField, Surface

Example:

@Composable
fun MaterialExample() {
    MaterialTheme {
        Surface(
            modifier = Modifier.padding(16.dp),
            shape = MaterialTheme.shapes.medium,
            color = MaterialTheme.colors.surface
        ) {
            Column {
                Text(
                    text = "Material Design",
                    style = MaterialTheme.typography.h6
                )
                Button(
                    onClick = { /* Handle click */ },
                    colors = ButtonDefaults.buttonColors(
                        backgroundColor = MaterialTheme.colors.primary
                    )
                ) {
                    Text("Material Button")
                }
            }
        }
    }
}

WHY IT MATTERS

  • Higher layers = simpler but less flexible
  • Lower layers = more control but more complex
  • Example: animateColorAsState (high) vs Animatable (low)
  • Components are composable (Button uses Surface + Row + Text)

PRACTICAL BENEFITS

  • Target only needed modules
  • Use high-level components when possible
  • Drop to lower layers for custom needs
  • Balance accessibility with customization
  • Create custom modifiers for reusable UI patterns (see Jetpack Compose: Custom Modifiers)

KEY POINT

Layered architecture gives flexibility to choose the right abstraction level for each UI challenge.