LazyColumn in Jetpack Compose (Complete Guide + Examples)

In almost every Android app, you need to show a list.

It can be a list of products, messages, contacts, or settings.

In Jetpack Compose, this is done using LazyColumn.

At first, it may feel confusing.

But once you understand the basics, it becomes very simple.

In this guide, you will learn:

  • How to create a simple list
  • How LazyColumn works internally
  • How to handle selection
  • How to create expandable lists
  • How to use sticky headers

Step 1: Create a Simple List

First, we need some data.

 val itemsList = List(20) { "Item ${it + 1}" } 

This creates 20 simple items.


Step 2: Add LazyColumn
 
LazyColumn {

}

LazyColumn is similar to RecyclerView.

It only renders items that are visible on the screen.


Step 3: Display Items

LazyColumn {
	items(itemsList) { item ->
    	Text(text = item)
	}
}

Watch step-by-step video down below:

Now your list is visible and scrollable.


Improve UI with Padding and Divider


LazyColumn {
  items(itemsList) { item ->

      Column {

          Text(
              text = item,
              modifier = Modifier
                  .fillMaxWidth()
                  .padding(16.dp)
          )

          Divider()

      }

  }

}

Now each item has spacing and a divider.


Important Concept: Why LazyColumn?

LazyColumn does not render all items at once.

If you have 1000 items, it only renders what is visible.

This makes your app fast and efficient.


Multi Select List Example

Now let’s build something more practical.

We will allow users to select multiple items.

 val items = List(20) { "Item ${it + 1}" } val selectedItems = remember { mutableStateListOf() } 

Now handle click and selection.

 
items(items) { item ->
  val isSelected = selectedItems.contains(item)

  Text(
      text = item,
      modifier = Modifier
          .fillMaxWidth()
          .clickable {
              if (isSelected) {
                  selectedItems.remove(item)
              } else {
                  selectedItems.add(item)
              }
          }
          .background(
              if (isSelected) Color.LightGray
              else Color.Transparent
          )
          .padding(16.dp)
  )

}

Now users can select multiple items.


Expandable List Example

Sometimes you want to show more details when an item is clicked.


var expandedItem by remember { 
	mutableStateOf String>(null) 
} 
 
items(items) { item ->
  Column(
      modifier = Modifier
          .fillMaxWidth()
          .clickable {
              expandedItem =
                  if (expandedItem == item) null else item
          }
          .padding(16.dp)
  ) {

      Text(text = item)

      if (expandedItem == item) {
          Text(
              text = "Extra details about $item",
              modifier = Modifier.padding(top = 8.dp)
          )
      }
  }

}

Now each item expands and collapses on click.


Sticky Header Example

You can also group items and keep headers fixed.

 
LazyColumn {
  groupedData.forEach { key, items ->

      stickyHeader {
          Text(
              text = key,
              modifier = Modifier
                  .fillMaxWidth()
                  .background(Color.LightGray)
                  .padding(12.dp)
          )
      }

      items(items.size) { index ->
          Text(
              text = items[index].title,
              modifier = Modifier.padding(16.dp)
          )
      }
  }
}

The header stays visible while scrolling.


Common Beginner Mistake

Do not use Column for large lists. It will render everything at once and slow down your app. Always use LazyColumn.

How to Start

If you are starting today:

  • Create your data
  • Use LazyColumn
  • Display items using items()
  • Add features step by step

Final Thoughts

LazyColumn is simple once you understand it.

Start with a basic list.

Then move to selection, expansion, and grouping.

This is how real apps are built.

If you want more simple Jetpack Compose tutorials, stay connected with Coding Reel.

Post a Comment

Share your thoughts ...

Previous Post Next Post