Jetpack Compose Messages UI (with Source Code)

jetpack compose list example

This is a UI that contains a list of messages. You can download the source code for free below.

The items in the list contains the person’s image, name, time at which the message is sent, and the actual message. All these things are arranged using Column and Row composable.

The MessagesData is the data class that holds the user image, name, message, and time. All these items are placed inside the Box layout.

Final Output:

If the video isn’t working, watch it on the YouTube.

Helpful Links to Understand the Code:

Resources Used in the Project:

Here are the Gradle files used in the project.

The images of people are downloaded from Pixabay. Crop them in a square shape before adding to the project.

Jetpack Compose Messages UI Source Code:

MainActivity.kt:

import android.content.Context
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

/*
You can use the following code for commercial purposes with some restrictions.
Read the full license here: https://semicolonspace.com/semicolonspace-license/
For more designs with source code,
visit: https://semicolonspace.com/jetpack-compose-samples/
 */
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BlogPostsTheme(darkTheme = false) {
                Column(
                    modifier = Modifier.fillMaxSize(),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally
                ) {
                    Messages1()
                }
            }
        }
    }
}

private lateinit var messagesList: ArrayList<MessagesData>

@Composable
fun TopAppbarMessages(context: Context = LocalContext.current.applicationContext) {
    TopAppBar(
        title = {
            Text(
                text = "Messages",
                maxLines = 1,
                overflow = TextOverflow.Ellipsis
            )
        },
        backgroundColor = MaterialTheme.colors.background,
        elevation = 4.dp,
        navigationIcon = {
            IconButton(onClick = {
                Toast.makeText(context, "Nav Button", Toast.LENGTH_SHORT).show()
            }) {
                Icon(
                    Icons.Filled.ArrowBack,
                    contentDescription = "Go back",
                )
            }
        }
    )
}

@Composable
fun Messages1() {

    // This is to check if the messagesList has data or not
    // Initially it is false
    var listPrepared by remember {
        mutableStateOf(false)
    }

    if (listPrepared) {

        TopAppbarMessages()

        LazyColumn(
            modifier = Modifier.fillMaxSize()
        ) {
            items(messagesList) { itemObject ->
                MessagesItemStyle(item = itemObject)
            }
        }
    }

    // This is called when the user first opens the activity
    // So, add data to messagesList here
    LaunchedEffect(Unit) {
        withContext(Dispatchers.Default) {
            prepareMessagesList()
            listPrepared = true
        }
    }

}

@Composable
fun MessagesItemStyle(
    item: MessagesData,
    context: Context = LocalContext.current.applicationContext
) {

    Box(
        modifier = Modifier
            .clickable(
                onClick = {
                    Toast.makeText(context, item.name, Toast.LENGTH_SHORT).show()
                }
            )
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {

            // Profile image
            Image(
                modifier = Modifier
                    .clip(shape = CircleShape)
                    .size(56.dp),
                painter = painterResource(id = item.image),
                contentDescription = item.name
            )

            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(start = 12.dp)
            ) {

                Row(
                    modifier = Modifier
                        .fillMaxWidth(),
                    horizontalArrangement = Arrangement.SpaceBetween
                ) {

                    // Text that shows the name
                    Text(
                        text = item.name,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        style = TextStyle(
                            fontFamily = FontFamily(Font(R.font.roboto_medium, FontWeight.Medium)),
                            fontSize = 18.sp,
                            color = Color.Black
                        )
                    )

                    // Text that shows the time
                    Text(
                        text = item.time,
                        style = TextStyle(
                            fontFamily = FontFamily(Font(R.font.roboto_regular, FontWeight.Normal)),
                            fontSize = 14.sp,
                            color = Color.Black
                        )
                    )

                }

                // Text that shows the message
                Text(
                    modifier = Modifier
                        .padding(top = 2.dp),
                    text = item.message,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                    style = TextStyle(
                        fontFamily = FontFamily(Font(R.font.roboto_regular, FontWeight.Normal)),
                        fontSize = 16.sp,
                        color = Color.Black
                    )
                )

            }
        }
    }
}

private fun prepareMessagesList() {
    messagesList = ArrayList()

    messagesList.add(
        MessagesData(
            R.drawable.people_abby,
            "Abby",
            "Cool. We meet tomorrow",
            "30 min"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_emilia,
            "Emilia",
            "Why are you not picking up my call?",
            "32 min"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_emma,
            "Emma",
            "Tom doesn't have to help",
            "40 min"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_grace,
            "Grace",
            "The school principal was so mean that all the children were scared of him",
            "3 hours"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_hannah,
            "Hannah",
            "I'm curious to know why they removed my name from the list",
            "5 hours"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_isabella,
            "Isabella",
            "Do you really think you'd be happy in a job like that?",
            "10 hours"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_lucy,
            "Lucy",
            "Would you like your cash in tens or twenties?",
            "12 hours"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_olivia,
            "Olivia",
            "If you hurry, there still might be some choice items left for you to buy",
            "1 Nov"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_scarlett,
            "Scarlett",
            "How can she afford a multi-million dollar house?",
            "31 Oct"
        )
    )

    messagesList.add(
        MessagesData(
            R.drawable.people_victoria,
            "Victoria",
            "She found the necklace in a safe at the bottom of her parents' closet",
            "31 Oct"
        )
    )

}

data class MessagesData(
    val image: Int,
    val name: String,
    val message: String,
    val time: String
)

Related Articles:

Leave a Comment