How to Implement a Card in Jetpack Compose?

Jetpack Compose Card

In this article, we’ll learn how to implement Card in Android Jetpack Compose along with examples. If you are familiar with XML, this is the CardView.

Prerequisites:

What is Card in Jetpack Compose?

Cards are surfaces that display content and actions. We can set the shadow, border, and corner radius to make it more appealing.

Example:

card example

For this article, create an empty Jetpack Compose project and open MainActivity.kt. Create a MyUI() composable outside the class and all it from the onCreate() method.

// we'll use the following imports
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.BorderStroke
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            YourProjectNameTheme(darkTheme = false) {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    Column(
                        modifier = Modifier.fillMaxSize(),
                        verticalArrangement = Arrangement.Center,
                        horizontalAlignment = Alignment.CenterHorizontally
                    ) {
                        MyUI()
                    }
                }
            }
        }
    }
}

@Composable
fun MyUI() {

}

We will write our code in MyUI().

Jetpack Compose provides Card() composable. There are two overloads of the function. Start typing Card and select the one without the onClick parameter. We will talk about clickable cards later.

jetpack compose card composable

The composable looks like this:

@Composable
@NonRestartableComposable
fun Card(
    modifier: Modifier = Modifier,
    shape: Shape = MaterialTheme.shapes.medium,
    backgroundColor: Color = MaterialTheme.colors.surface,
    contentColor: Color = contentColorFor(backgroundColor),
    border: BorderStroke? = null,
    elevation: Dp = 1.dp,
    content: @Composable () -> Unit
)

Let’s look at the parameters:

modifierThe modifier to change the layout of the card.

shapeThe shape of the card.

backgroundColor – The background color of the card.

contentColor – The preferred color of the card content (children).

border – The border around the card.

elevation – The shadow below the card.

content – The content (children) of the card.

Simple Card Example:

@Composable
fun MyUI() {
    Card {
        Text(
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

Jetpack Compose Card Example

Let’s add some padding to the content.

@Composable
fun MyUI() {
    Card {
        Text(
            modifier = Modifier.padding(horizontal = 8.dp, vertical = 6.dp),
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

Jetpack Compose Card Padding

Card Shadow and Elevation:

The elevation parameter is used to add the shadow below the card.

@Composable
fun MyUI() {
    Card(elevation = 4.dp) {
        Text(
            modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

card elevation and shadow

Card Border:

We can customize the card border using BorderStroke() method.

@Composable
fun MyUI() {
    Card(
        border = BorderStroke(width = 2.dp, color = Color.Green),
        elevation = 4.dp
    ) {
        Text(
            modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

card border

Read More: Colors in Jetpack Compose

Card Background Color:

We can use the backgroundColor parameter to change the background color of the card.

@Composable
fun MyUI() {
    Card(
        backgroundColor = Color.Green.copy(alpha = 0.2f)
    ) {
        Text(
            modifier = Modifier.padding(horizontal = 10.dp, vertical = 4.dp),
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

card background color

Card with Gradient Background:

In Jetpack Compose, Brush API is used to create gradient backgrounds. But, Card() composable doesn’t have a brush parameter. So, create a Column() or Box() with a gradient background and put it in the content block.

@Composable
fun MyUI() {
    Card(
        elevation = 4.dp,
        shape = RoundedCornerShape(size = 12.dp)
    ) {
        Column(
            modifier = Modifier
                .background(
                    brush = Brush.horizontalGradient(
                        listOf(
                            Color(0xFFF518A0),
                            Color(0xFFB232BD)
                        )
                    )
                )
                .padding(all = 32.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                text = "SemicolonSpace",
                fontSize = 20.sp,
                color = Color.White
            )
        }
    }
}

Output:

Gradient Background

Card with Corner Radius:

We can create a card with rounded corners using the shape parameter. To adjust the corner radius, call RoundedCornerShape() method and pass the radius value.

@Composable
fun MyUI() {
    Card(
        shape = RoundedCornerShape(size = 26.dp),
        border = BorderStroke(width = 1.dp, color = Color.Green),
        elevation = 4.dp
    ) {
        Text(
            modifier = Modifier.padding(horizontal = 14.dp, vertical = 8.dp),
            text = "SemicolonSpace",
            fontSize = 20.sp
        )
    }
}

Output:

card rounded corners

Card with Image and Text:

Let’s make this card:

card with image text example

First, download the image from Pixabay. Next, rename it to dog.jpg and put it in the drawable folder. The image and text are in a row. So, create a Row() and add Image() and Text() in it. Put the Row() in the Card().

@Composable
fun MyUI() {
    Card(
        elevation = 4.dp,
        shape = RoundedCornerShape(size = 12.dp)
    ) {
        Row(
            modifier = Modifier.padding(all = 12.dp),
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.Center
        ) {
            Image(
                modifier = Modifier
                    .clip(shape = CircleShape)
                    .size(size = 62.dp),
                painter = painterResource(id = R.drawable.dog),
                contentDescription = "lucy pic",
                contentScale = ContentScale.Crop
            )
            Spacer(modifier = Modifier.width(width = 8.dp)) // gap between image and text
            Text(
                text = "Hi! I'm Lucy",
                fontSize = 20.sp,
                fontWeight = FontWeight.Medium
            )
        }
    }
}

Output:

card with image text example

Clickable Card in Jetpack Compose:

There is an overload of Card() with the onClick parameter. But, currently, it is an experimental API. So, instead of that, let’s use the Modifier.clickable{} method.

@Composable
fun MyUI(context: Context = LocalContext.current.applicationContext) {
    Card(
        elevation = 4.dp,
        shape = RoundedCornerShape(size = 12.dp),
        modifier = Modifier.clickable {
            Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show()
        }
    ) {
        Column(
            modifier = Modifier.padding(all = 8.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                text = "SemicolonSpace",
                fontSize = 20.sp
            )
        }
    }
}

Output:

card click ripple problem

From the output, you can see that the ripple is overlapping the card. We can fix this by setting the clickable{} on the Column() (instead of the Card()).

@Composable
fun MyUI(context: Context = LocalContext.current.applicationContext) {
    Card(
        elevation = 4.dp,
        shape = RoundedCornerShape(size = 12.dp)
    ) {
        Column(
            modifier = Modifier
                .clickable {
                    Toast
                        .makeText(context, "Click", Toast.LENGTH_SHORT)
                        .show()
                }
                .padding(all = 8.dp),
            verticalArrangement = Arrangement.Center,
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text(
                text = "SemicolonSpace",
                fontSize = 20.sp
            )
        }
    }
}

Output:

card ripple fix

This is all about Card in Android Jetpack Compose. I hope you have learned something new. If you have any doubts, comment below.

Related:

References:

1 thought on “How to Implement a Card in Jetpack Compose?”

  1. Just one, a little bit picky, comment from my side. Compose does not provide us with Card component, material library for compose does. This is important for people that does not want to use material library or who work with compose in other platforms

    Reply

Leave a Comment