← All courses

Lists with LazyColumn & Grids

🗓 May 31, 2026 ⏱ 2 min read

Why “Lazy”?

A regular Column builds all its children at once — fine for a few items, disastrous for thousands. LazyColumn and LazyRow only compose the items currently visible, recycling as you scroll. They replace the old RecyclerView + Adapter + ViewHolder boilerplate with a few lines.

A basic list

@Composable
fun UserList(users: List<User>) {
    LazyColumn(
        contentPadding = PaddingValues(12.dp),
        verticalArrangement = Arrangement.spacedBy(8.dp)
    ) {
        items(users, key = { it.id }) { user ->
            ListItem(
                headlineContent = { Text(user.name) },
                supportingContent = { Text(user.email) }
            )
        }
    }
}

Always pass a key

The key = { it.id } gives each item a stable identity so Compose can recycle and animate correctly when the list changes (insertions, deletions, reorders). Without it, updates can be wrong or janky.

Headers, sections and mixed content

LazyColumn {
    item { Text("Featured", style = MaterialTheme.typography.titleLarge) }
    items(featured) { FeatureCard(it) }

    item { Text("All users") }
    items(users, key = { it.id }) { UserRow(it) }
}

Grids

LazyVerticalGrid(
    columns = GridCells.Fixed(2),     // or GridCells.Adaptive(120.dp)
    contentPadding = PaddingValues(8.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalArrangement = Arrangement.spacedBy(8.dp)
) {
    items(photos, key = { it.id }) { photo -> PhotoCard(photo) }
}

Reacting to scroll

val state = rememberLazyListState()
LazyColumn(state = state) { /* ... */ }
// e.g. show a "scroll to top" button when state.firstVisibleItemIndex > 0

Common mistakes

  • Forgetting the key — causes wrong recycling and lost scroll/animation.
  • Putting a LazyColumn inside a scrolling Column (infinite height error) — let the LazyColumn do the scrolling.
  • Loading images synchronously — use Coil’s AsyncImage.
Summary: Use LazyColumn/LazyRow/LazyVerticalGrid for scrolling content, always pass a stable key, and mix item and items for headers and sections.