In many scenarios, you may want to display a collection of items onto a screen. This can usually be achieved with using either a Column or Row Composable.
Displaying a list of items
Let us try to add a list of items using a Row Composable.
@Composable
fun FoodList() {
Row(modifier = Modifier
.fillMaxWidth()
.horizontalScroll(state = rememberScrollState())) {
getFood().forEach {
FoodItem(food = it)
}
}
}
However, these Composables may not fit your needs.
For example, if you have a large list of items, you may not want to load all of them at once. Column and Row Composables will load all the items at once, which can cause performance issues.
This is where Composable like LazyColumn and LazyRow come in handy. These Composables are optimized for displaying large lists of data.
They also support lazy loading, which means that they will only load the items that are currently visible on the screen. This can help improve the performance of your app.
As their names suggest, LazyColumn is used to display a list of items in a column, while LazyRow is used to display a list of items in a row.
These Composables are a little different to regular layouts, instead of accepting a @Composable block, they accept a LazyListScope block.
This usually offers a items() function, which can be used to add items to the list.
The LazyListScope block also offers a item() function, which can be used to add a single item to the list.
Displaying a list of items
Let us try to add a list of items using a LazyColumn Composable.
@Composable
fun FoodList() {
LazyColumn(modifier = Modifier
.fillMaxHeight()){
items(getFood()) { food ->
FoodItem(food = food)
}
}
}
Let us add a LazyRow Composable to display a list of items in a row.
@Composable
fun FoodList() {
LazyRow(modifier = Modifier
.fillMaxWidth()){
items(getFood()) { food ->
FoodItem(food = food)
}
}
}
Lazy Grids
In addition to LazyColumn and LazyRow, there are also LazyVerticalGrid and LazyHorizontalGrid Composables.
These Composables are used to display a list of items in a grid.
-
LazyVerticalGridis used to display a list of items in a grid, with the items laid out vertically, in a scrollable container, spanned across multiple columns. -
LazyHorizontalGridis used to display a list of items in a grid, with the items laid out horizontally, in a scrollable container, spanned across multiple rows.
The columns parameter in LazyVerticalGrid and rows parameter in LazyHorizontalGrid can be used to specify the number of columns or rows in the grid.
Both columns and rows parameters accept a GridCells object, which can be used to specify the number of columns or rows in the grid respectively.
The GridCells object offers three different options:
-
GridCells.Fixed(count: Int)- This option is used to specify a fixed number of columns or rows in the grid. -
GridCells.Adaptive(minSize: Int)- This option is used to specify a minimum size for the columns or rows in the grid. The number of columns or rows will be calculated based on the minimum size and the available space. -
GridCells.Adaptive(minSize: Int, maxSize: Int)- This option is used to specify a minimum and maximum size for the columns or rows in the grid. The number of columns or rows will be calculated based on the minimum and maximum size and the available space.
Displaying a grid of items
Let us try to add a grid of items using a LazyVerticalGrid Composable.
LazyVerticalGrid(
columns = GridCells.Fixed(2), ){
items(getFood()){ food ->
FoodItem(food = food)
}
}
Content Padding
By default, the items in a LazyColumn or LazyRow will be placed edge to edge.
If you want to add some padding around the items, you can use the contentPadding parameter.
The contentPadding parameter accepts a PaddingValues object, which can be used to specify the padding around the items.
The PaddingValues object offers four different options:
-
PaddingValues(all: Dp)- This option is used to specify the same padding on all sides. -
PaddingValues(horizontal: Dp, vertical: Dp)- This option is used to specify the horizontal and vertical padding. -
PaddingValues(start: Dp, top: Dp, end: Dp, bottom: Dp)- This option is used to specify the padding on each side. -
PaddingValues(left: Dp, top: Dp, right: Dp, bottom: Dp)- This option is used to specify the padding on each side.
Content Padding
Let us try to add some padding around the items in a LazyVerticalGrid Composable.
LazyVerticalGrid(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(16.dp)
){
items(getFood()){ food ->
FoodItem(food = food)
}
}
Content Spacing
In order to add some spacing between the items in a LazyColumn or LazyRow, you can use the verticalArrangement and horizontalArrangement parameters.
The verticalArrangement and horizontalArrangement parameters accept a Arrangement object, which can be used to specify the spacing between the items.
The Arrangement object offers several different options:
-
Arrangement.spacedBy(space: Dp)- This option is used to specify the same spacing between all the items. -
Arrangement.spacedBy(space: Dp, alignment: Alignment)- This option is used to specify the same spacing between all the items, with the specified alignment.
For lazy grids, you can use both the verticalArrangement and horizontalArrangement parameters to specify the spacing between the items.
Content Spacing
Let us try to add some spacing between the items in a LazyVerticalGrid Composable.
LazyVerticalGrid(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
){
items(getFood()){ food ->
FoodItem(food = food)
}
}
Item Keys
By default, each item in a Lazy layout will be referenced by its index in the list. This can cause issues if the list is updated, as the items will be re-arranged.
If you imagine the scenario of a LazyColumn, when a row changes item position, the user would lose their scroll position within the column.
To avoid this issue, you can specify a key for each item in the list. This key will be used to reference the item, instead of the index.
The items() function offers an optional key parameter, which can be used to specify a key for each item in the list.
Keys usually help Compose to handle reorderings correctly.
One limitation of using keys is that you can only use data types that are supported by the Android Bundle class.
Item Keys
Let us try to add some keys to the items in a LazyVerticalGrid Composable.
LazyVerticalGrid(
columns = GridCells.Fixed(2),
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
){
items(getFood(), key = { food -> food.id }){ food ->
FoodItem(food = food)
}
}
Conclusion
In this lesson, we learned about the Lazy layouts in Jetpack Compose. We have been able to see how, by using Lazy layouts, we can display a list of items in a performant way.
We have also seen how we can use Lazy layouts to display a grid of items, and how we can add padding and spacing to the items.
In our next episode, we will learn about state management in Jetpack Compose.