In this lesson, you will learn how to populate a list of room in our empty rooms screen (you should have created this activity in the last lab).
When you want to create a list view you can use the Row
and Column
composables with the modifier verticalScroll
to create a list of elements. But if you have a lot of elements, it’s not the best way to do it.
You should use a LazyColumn
or LazyRow
composables (equivalent to the legacy RecyclerView widget). These elements are able to manage a large data sets and scrool between elements.
LazyColumn {
item {
Header()
}
items(data) { item ->
PhotoItem(item)
}
}
The Lazy components are responsible for adding the each item’s content as required by the layout and scroll position.
For example, if your list shows music collection, each item might represent a single album. The composable creates only as many view items as are needed to display the on-screen portion of the dynamic content, plus a few extra. As the user scrolls through the list, the composable takes the off-screen views and rebinds them to the data which is scrolling onto the screen.
Compose provide also a LazyVerticalGrid
and LazyHorizontalGrid
to display a grid of elements. Grids have the same powerful API capabilities as lists.
If you need to create a very large list of elements, you can use the LazyVerticalStaggeredGrid to automatically load more data when the user scrolls to the end of the list.
Open the activity created in the last labs and called RoomListActivity
. For the moment we have a basic composable with a single Text component. We will now add a list of rooms.
You can create a new composable called RoomItem
to display a room in the list. This composable will take a Room
object as parameter and display the name of the room and the current temperature.
@Composable
fun RoomItem(room: RoomDto, modifier: Modifier = Modifier) {
Card(colors = CardDefaults.cardColors(containerColor = Color.Transparent),
border = BorderStroke(1.dp, PurpleGrey80)
) {
Row(
modifier = modifier.padding(20.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Column {
Text(
text = room.name,
style = MaterialTheme.typography.bodyLarge,
fontWeight = FontWeight.Bold
)
Text(
text = "Target temperature : " + (room.targetTemperature?.toString() ?: "?") + "°",
style = MaterialTheme.typography.bodySmall
)
}
Text(
text = (room.currentTemperature?.toString() ?: "?") + "°",
style = MaterialTheme.typography.headlineLarge,
textAlign = TextAlign.Right,
modifier = Modifier.fillMaxSize()
)
}
}
}
This composable is a Card
with a Row
inside. The Row
contains a Column
with the room name and the target temperature and a Text
with the current temperature. We used different styles to display the text.
You can add a function to preview this composable
@Preview(showBackground = true)
@Composable
fun RoomItemPreview() {
AutomacorpTheme {
RoomItem(RoomService.ROOMS[0])
}
}
You can now use a LazyColumn
to display the list of rooms. You can use the items
function to iterate over the list of rooms and display a RoomItem
for each room.
LazyColumn(
contentPadding = PaddingValues(4.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(innerPadding),
) {
val rooms = RoomService.findAll()
items(rooms, key = { it.id }) {
RoomItem(
room = it,
modifier = Modifier
)
}
}
Now if you run your app, you should see the list of rooms.
Now we will add a click listener on the RoomItem
to open the detail of a room when the user clicks on a room. You can add the clickable
modifier to each item in the grid to implement this behavior.
items(rooms, key = { it.id }) {
RoomItem(
room = it,
modifier = Modifier.clickable { openRoom(it.id) },
)
}
Now you can create a function openRoom
to create an Intent to open the detail of a room (ie RoomDetailActivity
).
For the moment, RoomDetailActivity
should return on the 'MainActicity` when the user clicks on the back button. You can update the function to return on the list of rooms.
If you want more explanations about list and grid you can read this article made by Google