Dev-Mind

16/08/2024
Android
 

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).

Create an activity list

LazyColumn & LazyRow

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.

Android RecyclerView

Compose provide also a LazyVerticalGrid and LazyHorizontalGrid to display a grid of elements. Grids have the same powerful API capabilities as lists.

Grid example

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.

: Display the room 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.

Create a composable to display a room in the list

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.

Item example
@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])
    }
}

Update the activity to display the list of rooms

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.

Item example

Open a room detail when clicking on a room

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.

More…​

If you want more explanations about list and grid you can read this article made by Google