What is the Jetpack Compose equivalent of RecyclerView or ListView?

Ryan M picture Ryan M · Mar 19, 2020 · Viewed 7.1k times · Source

In Jetpack Compose, how can I display a large list of data while laying out only the visible items, instead of composing and laying out every item on the initial layout pass? This would be similar to RecyclerView and ListView in the View toolkit.

One could use a for loop to place all of the components inside of a Column in a VerticalScroller, but this would result in dropped frames and poor performance on larger numbers of items.


Note: this is intended as a canonical self-answered question to pre-empt/handle similar questions

Answer

Ryan M picture Ryan M · Mar 19, 2020

The equivalent component to RecyclerView or ListView in Jetpack Compose is LazyColumn for a vertical list and LazyRow for a horizontal list. These compose and lay out only the currently visible items.

You can use it by formatting your data as a list and passing it with a @Composable callback that emits the UI for a given item in the list. For example:

val myData = listOf("Hello,", "world!")
LazyColumn {
    items(myData) { item ->
        Text(text = item)
    }
}
val myData = listOf("Hello,", "world!")
LazyRow { 
    items(myData) { item ->
        Text(text = item)
    }
}

You can also specify individual items one at a time:

LazyColumn {
    item {
        Text("Hello,")
    }
    item {
        Text("world!")
    }
}
LazyRow { 
    item {
        Text("Hello,")
    }
    item {
        Text("world!")
    }
}

There are also indexed variants, which provide the index in the collection in addition to the item itself:

val myData = listOf("Hello,", "world!")
LazyColumn {
    itemsIndexed(myData) { index, item ->
        Text(text = "Item #$index is $item")
    }
}
val myData = listOf("Hello,", "world!")
LazyRow { 
    itemsIndexed(myData) { index, item ->
        Text(text = "Item #$index is $item")
    }
}

These APIs were, in previous releases, known as AdapterList, LazyColumnItems/LazyRowItems, and LazyColumnFor/LazyRowFor.