Creating a vertical list with Jetpack Compose
Android is one of the most popular and widely used operating systems in the world, powering billions of devices ranging from smartphones to smartwatches. As an experienced Android developer, I have witnessed the evolution of this platform and learned a lot from its challenges and opportunities. However, writing articles is a new skill for me, and I want to share my knowledge and insights with other developers and enthusiasts interested in Android development. This article is not just a documentation of my initial steps with Jetpack Compose; it’s a narrative of exploration, challenges encountered, insights gained, and the synthesis of my extensive Android development journey with this innovative UI toolkit.
We are going to implement the list using jetpack compose the final result will look like this.
Starting from scratch, Jetpack composes views and provides runtime rendering and creation. For creating a list using Compose, we don’t need the XML layout at all. So, Let’s create a blank activity project and start writing code for the listing using Compose.
Empty activity will provide you with the Greeting method in MainActivity. You will now remove the Greetings method and implement the Customize list. In the basic list, there are two Text holders for the Title and Description and an Image holder (previously known as TextView and ImageView, respectively) for the image of the item. You can customize your list once you understand its implementation.
//Call the LazyColumnInit from your Surface method where the Greeting method was placed
@Composable
fun LazyColumnInit() {
//Accessing the context from the composable to show the Toast
val context = LocalContext.current
//Declaring the list using remember will help in remembering the stae of the list
//generateListData populate the exampleItem to the mutablelist in seperate function
val data by rememberUpdatedState(generateListData())
//Replace numberInInt to any int you want
LazyColumn(Modifier.fillMaxSize()) {
items(data.size) { index ->
SetListItem(data[index])
if (index != data.lastIndex) {
Divider(
modifier = Modifier
.padding(vertical = numberInInt.dp)
.height(numberInInt.dp),
color = MaterialTheme.colorScheme.primary,
thickness = numberInInt.dp
)
}
}
//Change Toast to make your customize functions or remove item to remove buttons from list end
item {
LazyRowInit(
onButton1Click = {
Toast.makeText(
context, "Button One Clicked", Toast.LENGTH_LONG
).show()
},
onButton2Click = {
Toast.makeText(
context, "Button Two Clicked", Toast.LENGTH_LONG
).show()
}
)
}
}
}
The above code consists of a LazyColumn that displays a list of items using SetListItem(a method defined later in the article), and between these items, it adds a Divider.
The LazyColumn is a Composable that is typically used for displaying vertically scrolling lists of items efficiently. Each item in the list is created using the items function based on the size of the provided data list.
The Divider separates the items in the list, and its appearance is customized using modifiers like padding, height, color, and thickness.
Finally, there’s an item block containing a LazyRowInit composable that has buttons and callback functions. These callbacks create toast messages when they are clicked.
Now define the SetListItem method implementation for setting each element in the list.
@Composable
fun SetListItem(exampleItem: ExampleItem) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Image(
painter = // You can customize image loading parameters here if needed
rememberAsyncImagePainter(
ImageRequest.Builder(LocalContext.current).data(data = exampleItem.imageUrl)
.apply(block = fun ImageRequest.Builder.() {
// You can customize image loading parameters here if needed
crossfade(true)
}).build()
), contentDescription = null, // Decorative image
modifier = Modifier
.size(numberInInt.dp) // Set the size of Image as per your requirement
.clip(CircleShape)
.background(MaterialTheme.colorScheme.primary)
)
Spacer(modifier = Modifier.width(numberInInt.dp))// Set value in integer
Column {
Text(text = exampleItem.title, style = MaterialTheme.typography.bodyLarge)
Text(text = exampleItem.description, style = MaterialTheme.typography.bodyMedium)
}
}
}
In the above code
Row
Composable is used to arrange items horizontally whereas anImage
Composable is used to display an image fetched fromUrl
usingCoil
library to load the image asynchronously. ASpacer
Composable is added to create space between theImage
and theColumn
using a width. TheColumn
Composable is used to arrange items vertically. It contains twoText
composable displaysexampleItem.title
andexampleItem.description
with different typography styles (bodyLarge
andbodyMedium
) from the currentMaterialTheme
.
Now define the data class that you want to load in your view as this article includes exampleItem
data class.
data class ExampleItem(
val id: Int, // Id of the element
val title: String, // Title for the element
val description: String, // Description or any other field
val imageUrl: String //Image url of the element
)
In the end, create a method generateListData() and populate your data to the view by adding exampleItem
in the mutablelist and passing it in the val data by rememberUpdatedState() as written in the previous code.
private fun generateListData(): List<ExampleItem> {
for (index in 1..10) {
list.add(
ExampleItem(
id = index,
title = "test $index",
description = "test description $index",
// you can use in testing : https://freepngimg.com/thumb/animation/4-2-animation-png-pic.png
imageUrl = ""
)
)
}
return list
}
Hurray! You have successfully implemented the vertical list using Compose Jetpack. Please feel free to provide feedback and ask any queries related to the article. Happy Coding!