Jetpack Compose Dating App Match Screen UI

Jetpack Compose Dating Match Screen UI

This is a dating app match screen UI made with Android Jetpack Compose. You can download the source code for free below.

The UI has a gradient background. It contains two titles, images of a couple with a love icon on top of them, and the other two buttons below. All of these things are put inside the Column.

The Jetpack Compose match screen takes parameters like primaryColor and backgroundColors. The background colors are a list of gradient colors. To change the status bar colors use systemUiController API.

The UI uses multiple APIs like Icon, OutlinedButton, Image, Icon, Row, etc… All of them are inside a Column layout with gradient background. The icons used are material icons. The title texts are “It’s a Match!” and “You and Grace like each other”.

For icons, I have set the elevation to 4 dp, shape to CircleShape, and contentScale to ContentScale.Crop. There are two icons at the bottom. They are “Message Her” and “Continue Swiping”.

Final output:

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

Helpful links to understand the code:

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.

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.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.outlined.Mail
import androidx.compose.material.icons.outlined.Swipe
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.google.accompanist.systemuicontroller.rememberSystemUiController

/*
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) {
                MatchScreenDatingApp()
            }
        }
    }
}

@Composable
private fun MatchScreenDatingApp(
    primaryColor: Color = Color(0xFFF518A0),
    backgroundColors: List<Color> =
        listOf(
            primaryColor,
            Color(0xFFB232BD)
        )
) {

    // change status bar color
    val systemUiController = rememberSystemUiController()
    systemUiController.setStatusBarColor(color = primaryColor)

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(brush = Brush.verticalGradient(backgroundColors))
            .padding(vertical = 64.dp),
        verticalArrangement = Arrangement.SpaceAround,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {

        Column(
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            MatchScreenTopText()
        }

        MatchScreenImagesBox(primaryColor = primaryColor)

        Row(
            modifier = Modifier.fillMaxWidth(),
            // Gap between two buttons = 24.dp
            horizontalArrangement = Arrangement.spacedBy(24.dp, Alignment.CenterHorizontally)
        ) {
            MatchScreenButtons(primaryColor = primaryColor)
        }

    }
}

@Composable
private fun MatchScreenTopText() {

    Text(
        text = "It’s a Match!", style = TextStyle(
            color = Color.White,
            fontWeight = FontWeight.Bold,
            fontSize = 32.sp
        )
    )

    Text(
        text = "You and Grace like each other", style = TextStyle(
            color = Color.White,
            fontWeight = FontWeight.Normal,
            fontSize = 20.sp
        )
    )
}

@Composable
private fun MatchScreenImagesBox(primaryColor: Color) {
    Box(contentAlignment = Alignment.Center) {

        Row {
            MatchScreenImageStyle(imageId = R.drawable.people_john)
            MatchScreenImageStyle(imageId = R.drawable.people_grace_1)
        }

        Icon(
            modifier = Modifier
                .background(color = primaryColor, shape = CircleShape)
                .border(width = 3.dp, color = Color.White, shape = CircleShape)
                .padding(12.dp),
            imageVector = Icons.Filled.Favorite,
            contentDescription = "Match",
            tint = Color.White
        )

    }
}

@Composable
private fun MatchScreenImageStyle(imageId: Int) {
    Image(
        modifier = Modifier
            .size(120.dp)
            .shadow(
                elevation = 4.dp,
                shape = CircleShape,
                clip = true
            )
            .clip(CircleShape)
            .border(width = 3.dp, color = Color.White, shape = CircleShape),
        painter = painterResource(id = imageId),
        contentDescription = "Image",
        contentScale = ContentScale.Crop
    )
}

@Composable
private fun MatchScreenButtons(primaryColor: Color) {
    ButtonStyles(imageVector = Icons.Outlined.Mail, text = "Message Her", primaryColor = primaryColor)
    ButtonStyles(imageVector = Icons.Outlined.Swipe, text = "Continue Swiping", primaryColor = primaryColor)
}

@Composable
private fun ButtonStyles(
    context: Context = LocalContext.current.applicationContext,
    imageVector: ImageVector,
    text: String,
    primaryColor: Color
) {
    OutlinedButton(
        modifier = Modifier.size(56.dp),
        shape = CircleShape,
        border = BorderStroke(0.dp, Color.Transparent),
        contentPadding = PaddingValues(6.dp),
        elevation = ButtonDefaults.elevation(defaultElevation = 4.dp),
        onClick = {
            Toast.makeText(context, text, Toast.LENGTH_SHORT).show()
        }) {
        Icon(
            modifier = Modifier.size(32.dp),
            imageVector = imageVector,
            contentDescription = text,
            tint = primaryColor
        )
    }
}

Related:

Leave a Comment