Nested LazyColumn in Jetpack Compose

Jetpack Compose Series Episode IV— Nested Lazy Column

When displaying groups of elements, we generally use columns and rows. But when it comes to displaying long lists, compose provides efficient alternatives like LazyColumn and LazyRow, which only render visible items in the screen.

This lazy loading approach improves performance and reduces memory consumption.

Before implementing Nested LazyColumn, let’s briefly go through some basics about available components to render large list.

I. LazyColumn & LazyRow

When rendering large datasets, we often use LazyColumn for vertical arrangements and LazyRow for horizontal.

Similar to RecyclerView, it support reverse layout, orientation adjustment, multiple view types, etc.

LazyColumn {
items(data) { item ->
Box(
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.background(Color.Magenta)
.padding(16.dp)
)
Spacer(modifier = Modifier.padding(8.dp))
}
}


LazyRow {
items(data) { item ->
Box(
modifier = Modifier
.width(100.dp)
.height(200.dp)
.background(Color.Magenta)
.padding(16.dp)
)
Spacer(modifier = Modifier.padding(8.dp))
}
}

Index Position in LazyList

LazyColumn and LazyRow provide an itemsIndexed function that allows us to access the index number of each item in the list.

  LazyColumn {
itemsIndexed(items = dataList) { index, data ->

if (index == 0) {

}else{

}
}
}

Unique ID for LazyList

The key parameter in the LazyList ensures that each item in the list has a stable and unique key, which is essential for efficient list updates and performance optimization.

LazyColumn {
items(items = allProductEntities, key = { item -> item.id }) { product ->
ProductItem(product) {
onProductClick(product.id.toString())
}
}
}

Multiple ViewType

If we want to display different view types, such as headers, footers, or items with distinct UI representations, we can use the index or check view-type from the list to display it accordingly.

Header & Footer Items in LazyColumn
LazyColumn {
itemsIndexed(items = dataList) { index, data ->

if (index == 0) {
HeroCard(data)
} else {
when (data.categoryType) {

CategoryType.Recent -> {
RecentItem(data) {
onRecentItemClick(data.id))
}
}

CategoryType.Popular -> {
PopularItem(data) {
onPopularItemClick(data.id))
}
}

else -> {
TrendingItem(data) {
onTrendingItemClick(data.id)
}
}

}
}
}
}

Moreover, If there’s a need to append additional items to the list or add different components, we can use item function inside LazyList.

 LazyColumn {
item {
HeroCardItem()
}
items(data) { item ->
Box(
modifier = Modifier
.fillMaxWidth()
.height(200.dp)
.background(Color.Magenta)
.padding(16.dp)
)
Spacer(modifier = Modifier.padding(8.dp))
}
item {
FooterCardItem()
}

}

@Composable
fun HeroCardItem() {
Column {
Box(
modifier = Modifier
.height(500.dp)
.fillMaxWidth()
.padding(16.dp)
){
...
}
Spacer(modifier = Modifier.padding(8.dp))
}
}

@Composable
fun FooterCardItem() {
Column {
Box(
modifier = Modifier
.height(100.dp)
.fillMaxWidth()
.padding(16.dp)
){
...
}
Spacer(modifier = Modifier.padding(8.dp))
}
}

II. LazyGrid

With Compose, we can easily create grids using the Grid composable and its variants, such as LazyVerticalGrid and LazyHorizontalGrid with lazy loading capabilities.

We can define rows and columns in a grid by using the following types:

columns for LazyVerticalGrid and rows for LazyHorizontalGrid

— Adaptive: Adjusts the size of rows or columns based on content and available space.

--> (columns = GridCells.Adaptive(minSize = 128.dp))
--> (rows = GridCells.Adaptive(minSize = 128.dp))

— FixedSize: Specifies a fixed size for rows or columns.

--> (columns = GridCells.FixedSize(100.dp))
--> (rows = GridCells.FixedSize(100.dp))

— Fixed: Sets a fixed number of rows or columns.

--> (columns = GridCells.Fixed(4))
--> (rows = GridCells.Fixed(4))
--> (columns = StaggeredGridCells.Fixed(2)),
@Composable
fun ExampleVGrid(data: List<String>) {

LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 128.dp),
contentPadding = PaddingValues(8.dp)
) {
items(data.size) { index ->
Card(
modifier = Modifier
.padding(4.dp)
.fillMaxWidth(),
) {
Text(
text = data[index],
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
modifier = Modifier.padding(16.dp)
)
}
}

}

}

III. Flow Layout

Flow layout helps us arrange our elements in a natural flow. We have FlowColumn and FlowRow to arrange vertically and horizontally.

Note: FlowRow and FlowColumn are experimental.

Read more about FlowLayout

Kt. Academy

Nested LazyColumn in Jetpack Compose was originally published in Kt. Academy on Medium, where people are continuing the conversation by highlighting and responding to this story.

Continue ReadingNested LazyColumn in Jetpack Compose

End of content

No more pages to load