Fast Tutorial - Beautiful credit cards with JetPack Compose

Fast Tutorial - Beautiful credit cards with JetPack Compose

Written by Danubius IT Solutions

This fast tutorial shows how to create a list of credit cards with JetPack Compose. Just follow the steps and try out Google’s declarative UI framework today!

Prerequisites

  • Latest version of Android Studio

  • JDK 11 or higher

  • Physical or virtual device for testing

Anatomy

Credit card tutorial cover

The idea is very simple: Create a card, add a mesh gradient image, put over a box layout and take the parts to the right places. The key is the Box layout. With this composable, you can put elements in the 4 corners of the box. See the reference docs for more about Box layout.

Prepare

First of all, create a new Android Project and select Empty Compose Activity. Then clean up the sample code.

Get the image and font resources:

Put image resources to /res/drawable.

Create a new resource folder for fonts: /res/font and copy font files (Space Grotesk bold for cardholder name and Space mono regular for card number).

Create CreditCard() composable

Create a new Kotlin file under the ui package and name it CreditCard.kt. Start a new composable function and add empty Card() component:

@Composable

fun CreditCard() {

 

    Card(

        modifier = Modifier

            .height(200.dp),

        shape = RoundedCornerShape(8.dp),

        elevation = 8.dp

    ) { }

}

Add Image() inside card content for the mesh background:

@Composable

fun CreditCard(cardInfo: CardInfo) {

 

    Card(

        modifier = Modifier

            .height(200.dp),

        shape = RoundedCornerShape(8.dp),

        elevation = 8.dp

    ) {

        Image(

            painter = painterResource(id = R.drawable.card_mesh),

            contentDescription = "Card Background",

            contentScale = ContentScale.FillBounds

        )

    }

}

The FillBounds content scale will expand the image to match the size of the card.

After the image, put a new Box() layout with some padding:

Box(modifier = Modifier.padding(16.dp)) { }

Add Image() to the Box TopStart position and load the Visa logo.

Box(modifier = Modifier.padding(16.dp)) {

    Image(

        painter = painterResource(id = R.drawable.visa),

        contentDescription = "Visa",

        modifier = Modifier

            .width(86.dp)

            .align(Alignment.TopStart)

    )

}

Prepare the font faces to use for card number and cardholder texts. Open ui/theme/Type.kt and create new font families:

val SpaceMono = FontFamily(

    Font(R.font.space_mono_regular)

)

 

val SpaceGrotesk = FontFamily(

    Font(R.font.space_grotesk_bold, FontWeight.Bold)

)

Now you can use them in other composables.

To align the card number and the cardholder name under each other, we will use a Column() wrapper component and put the Text() inside it.

Box(modifier = Modifier.padding(16.dp)) {

    Image(

        painter = painterResource(id = R.drawable.visa),

        contentDescription = "Visa",

        modifier = Modifier

            .width(86.dp)

            .align(Alignment.TopStart)

    )

    Column(modifier = Modifier

            .align(Alignment.BottomStart)) {

        Text(

            text = "5435 9876 1234 6543",

            fontFamily = SpaceMono,

            letterSpacing = 1.2.sp,

            fontSize = 16.sp

        )

        Text(

            text = cardInfo.cardHolder,

            fontFamily = SpaceGrotesk,

            letterSpacing = 1.1.sp,

            fontSize = 16.sp

        )

    }

}

Showtime

The CreditCard() composable is ready to use, put inside your app component:

@Composable

fun DiCardApp() {

    DanubiusCreditCardTheme {

        Column(

            modifier = Modifier

                .fillMaxHeight()

                .padding(16.dp),

            verticalArrangement = Arrangement.spacedBy(16.dp)

        ) {

 

                CreditCard(cardInfo = CardInfo(

                    backgroundDrawable = R.drawable.card_mesh,

                    providerDrawable = R.drawable.mc,

                    cardNumber = "8547 9658 6325 4521",

                    cardHolder = "John Fluffy"

                ))

        }

    }

}

More than one

Create a new data class to hold the attributes of a CreditCard() composable, for example CardInfo.kt.

data class CardInfo(

    val cardNumber: String,

    val cardHolder: String,

    val providerDrawable: Int,

    val backgroundDrawable: Int

)

Create a fake list of cards:

val cards = listOf(

    CardInfo(

        backgroundDrawable = R.drawable.card_mesh,

        providerDrawable = R.drawable.mc,

        cardNumber = "8547 9658 6325 4521",

        cardHolder = "Jim Hopper"

    ),

    CardInfo(

        backgroundDrawable = R.drawable.card_mesh_2,

        providerDrawable = R.drawable.visa,

        cardNumber = "6582 4521 3256 8522",

        cardHolder = "Steve Harrington"

    ),

    CardInfo(

        backgroundDrawable = R.drawable.card_mesh_3,

        providerDrawable = R.drawable.visa,

        cardNumber = "9856 7452 2569 7413",

        cardHolder = "Joyce Byers"

    )

)

Change Column() component to LazyColumn() and load the items of cards list.

LazyColumn(

    modifier = Modifier

        .fillMaxHeight()

        .padding(16.dp),

    verticalArrangement = Arrangement.spacedBy(16.dp)

) {

    items(cards) { card ->

        CreditCard(cardInfo = card)

    }

}

Refactor the CardInfo component to display CardInfo object attributes. See the final implementation below:

@Composable

fun CreditCard(cardInfo: CardInfo) {

 

    Card(

        modifier = Modifier

            .height(200.dp),

        shape = RoundedCornerShape(8.dp),

        elevation = 8.dp

    ) {

        Image(

            painter = painterResource(id = cardInfo.backgroundDrawable),

            contentDescription = "Card Background",

            contentScale = ContentScale.FillBounds

        )

        Box(modifier = Modifier.padding(16.dp)) {

            Image(

                painter = painterResource(id = cardInfo.providerDrawable),

                contentDescription = "Visa",

                modifier = Modifier

                    .width(86.dp)

                    .align(Alignment.TopStart)

            )

            Column(modifier = Modifier.align(Alignment.BottomStart)) {

                Text(

                    text = cardInfo.cardNumber,

                    fontFamily = SpaceMono,

                    letterSpacing = 1.2.sp,

                    fontSize = 16.sp

                )

                Text(

                    text = cardInfo.cardHolder,

                    fontFamily = SpaceGrotesk,

                    letterSpacing = 1.1.sp,

                    fontSize = 16.sp

                )

            }

        }

 

    }

 

}

That’s it! You can play around with other backgrounds, fonts, and layouts. You can find the full example on GitHub in this repository. Don’t forget to ⭐️ the repository.

Credit card tutorial cover

Interested in IT solutions tailored to your business? Contact us for a free consultation, where we'll collaboratively explore your needs and our methodologies.

Read our tech blog

Prompt Engineering – Is it Fake or a Vital Skill for the AI-Powered Future?

Prompt Engineering – Is it Fake or a Vital Skill for the AI-Powered Future?

In our continued journey to innovate within the AI-driven customer support landscape, we would like to draw attention to a term that's often misunderstood outside tech circles: prompt engineering. Prompt engineering emerges as a cornerstone of AI engineering, vital for refining the capabilities of large language...

5 minutes
What Can We Achieve with Artificial Intelligence in Customer Service?

What Can We Achieve with Artificial Intelligence in Customer Service?

Artificial intelligence (AI) has emerged as a transformative force and our team here, at Danubius embarked on an ambitious journey to explore the real impact of AI's practical applications in enhancing customer support. The adventure began a little over half a year ago with an internal project that aimed to not...

6 minutes
Are You Wasting Money in Your Software Development Project?

Are You Wasting Money in Your Software Development Project?

Over the years, our team has encountered everything from project triumphs to near-misses, teaching us a crucial lesson: software development can be full of avoidable errors that can inflate costs and delay timelines. Post-Covid, many large firms are confronting IT expenditures that fail to meet expected value, highlighting a need for change.

14 minutes

Listen to our podcast below

Scrum Mastery Unveiled: Part 1

Scrum Mastery Unveiled: Part 1

Scrum Masters are more than just facilitators; they are often a key part of a development team, ensuring efficiency, timely delivery, and much more. We discussed their challenges with two of our experts, Zsofia Samodai and...

55 minutes
Hello, Danubius!

Hello, Danubius!

The two founders of Danubius IT Solutions, Peter Balogh and Peter Halasz, sat down to discuss the company's past, present, and future. Our discussions covered the creation and development of an organizational culture, as well as scaling the company from two coworkers to 100.

31 minutes