LazyColumn With Multi-Header In Jetpack Compose.
3 min readSep 23, 2023
In this article we will see how to make multiple headers for Lazy Column in Jetpack compose.
As you can see in the above video , we have a list of items , and all the items have a type (Animal , Flower, Furniture). We will arrange all the items according to their types and also see show/hide the items.
data class Item(
val id: Int,
val name: String,
val type: String
)
val itemList = listOf(
Item(
1, "Tiger", "Animal"
),
Item(
2, "Lion", "Animal"
),
Item(
3, "Deer", "Animal"
),
Item(
4, "Lotus", "Flower"
),
Item(
5, "Sunflower", "Flower"
),
Item(
6, "Rose", "Flower"
),
Item(
7, "Table", "Furniture"
),
Item(
8, "Chair", "Furniture"
),
Item(
9, "Bed", "Furniture"
),
Item(
10, "Monkey", "Animal"
),
)
First we defined the list of data with their type…
@Composable
fun LazyColumnWithMultiHeaderScreen(
modifier: Modifier
) {
// a mutable map variable , which indicate that item is visible or not
var isShow = remember {
mutableStateMapOf<String, Boolean>()
}
// by default we will store true , all the item will be visible
LaunchedEffect(key1 = Unit) {
isShow = isShow.apply {
itemList.associate { item ->
item.type to true
}.also {
putAll(it)
}
}
}
LazyColumn(
modifier = modifier
.padding(20.dp)
.fillMaxSize()
) {
val groupItems = itemList.groupBy { it.type }
groupItems.forEach { (type, items) ->
item {
Row(
modifier = Modifier
.padding(vertical = 15.dp)
.fillMaxWidth()
.toggleable(
value = isShow[type] == true,
onValueChange = {
isShow[type] = it
},
role = Role.Button
)
) {
Row(
modifier = Modifier.weight(1f)
) {
Text(
text = type,
style = MaterialTheme.typography.headlineLarge.copy(
color = Color.Black,
fontWeight = FontWeight.W700
),
)
Spacer(modifier = Modifier.width(10.dp))
Text(
text = "(${items.size})",
style = MaterialTheme.typography.headlineLarge.copy(
color = Color.Black,
),
)
}
Spacer(modifier = Modifier.width(10.dp))
Icon(
if (isShow[type] == true) Icons.Default.KeyboardArrowDown else Icons.Default.KeyboardArrowUp,
contentDescription = null,
modifier = Modifier.align(CenterVertically)
)
}
}
if (isShow[type] == true)
items(items, key = { it.id }) {
Text(
text = it.name, style = MaterialTheme.typography.bodyLarge.copy(
color = Color.DarkGray
),
modifier = Modifier.padding(top = 10.dp)
)
}
}
}
}
- As you can see in the above code , First we have defined a
isShow
variable , which is amutableStateMapOf<String,Boolean>
, which storetype
(Animals , Flowers , Furniture) and their correspondingtrue/false
value, so that it’s easy to keep track , which item we want to show/hide. - After that in the
LaunchEffect
we apply all thetype
totrue
, because by default all the item will be visible. - Now in the
LazyColumn
, first we group the items with their type , As you see with the help ofgroupBy{}
kotlin’s in-built function , it will returnMap<String, List<Item>>
. - After that use
forEach
loop which will return(type,List<Item>)
, In theitem{}
function , just write your header section with hide/show functionality - And In the
items{}
function , pass yourList<Item>
data , and it will show all theitems
corresponding to their type
That’s all for today my friends , Hope you enjoyed and learnt something new from this article.