Law

ID Proof UI in Jetpack Compose

The goal for this is to implement this UI (the image below) in Jetpack Compose.

iOS ID Proof

The Green Circle

The it.toString() is the ID Proof data in integer format.

Row(modifier = Modifier.padding(top = 10.dp)) {
    Text(
        it.toString(),
        modifier = Modifier.padding(8.dp).drawBehind {
            drawCircle(
                color = PrimaryGreen,
                radius = size.maxDimension
            )
        },
        color = White,
        style =
            TextStyle(
                fontFamily = openSansFont,
                fontWeight = FontWeight.SemiBold,
            ),
        fontSize = 16.sp
    )
}

Screenshot 2025-02-07 at 2

The Blue Capsule

I am going implement the blue capsule that will house our ID Proof label. I will add the code below inside our Row.

Box(
    modifier =
        Modifier
            .clip(RoundedCornerShape(70.dp))
            .background(ProofLightMode)
            .padding(start = 34.dp, end = 16.dp, top = 8.dp, bottom = 8.dp),
) {
    Text(
        "ID Proof",
        modifier = Modifier.padding(4.dp)
    )
}

Screenshot 2025-02-07 at 2

So far not good. Not there yet, alignment is off.

Remove Padding?

I removed the padding modifier inside our ID Proof Text and the UI now looks better previously.

Text("ID Proof")

Screenshot 2025-02-07 at 2

Next step, is both ID Proof and its label needs to overlap, so I'm going to replace Row with Box. And reorder the contents inside it. So the Box blue capsule will be on top now.

Screenshot 2025-02-07 at 2

Now, I'm going to move the ID proof Text() to the right.

Based on my research, we will use the .align modifier. And then, pass the BaseAlignment property. The values are based on my testing.

.align(BiasAlignment(-1.5f, 0.5f))

Updated Code

The updated code should look like the one below

// ID Proof
profileViewModel.profile.idProof.let {
    Box(modifier = Modifier.padding(top = 10.dp)) {
        Box(
            modifier =
                Modifier
                    .clip(RoundedCornerShape(70.dp))
                    .background(ProofLightMode)
                    .padding(start = 44.dp, end = 16.dp, top = 12.dp, bottom = 12.dp),
        ) {
            Text(
                "ID PROOF",
                style =
                    TextStyle(
                        fontFamily = openSansFont,
                        fontWeight = FontWeight.SemiBold,
                    ),
                fontSize = 16.sp
            )
        }
        Text(
            it.toString(),
            modifier = Modifier
                .padding(8.dp)
                .align(BiasAlignment(-1.22f, 0.5f))
                .drawBehind {
                    drawCircle(
                    color = PrimaryGreen,
                    radius = size.maxDimension,
                )
            },
            color = White,
            style =
                TextStyle(
                    fontFamily = openSansFont,
                    fontWeight = FontWeight.SemiBold,
                ),
            fontSize = 16.sp
        )
    }
}

Screenshot 2025-02-07 at 3

Almost there, next step is I will put a circle border around the green circle.

Okay, I have a problem. It seems, there is no way in adding a border with drawCircle, so I have to wrap the ID Proof Text() inside a Box.

With some updated adjustments the final code should look like the one below.

// ID Proof
profileViewModel.profile.idProof.let {
    Box(modifier = Modifier.padding(top = 10.dp), contentAlignment = Alignment.Center) {
        Box(
            modifier =
                Modifier
                    .clip(RoundedCornerShape(70.dp))
                    .background(ProofLightMode)
                    .padding(start = 60.dp, end = 16.dp, top = 8.dp, bottom = 8.dp),
        ) {
            Text(
                "ID PROOF",
                style =
                    TextStyle(
                        fontFamily = openSansFont,
                        fontWeight = FontWeight.SemiBold,
                    ),
                fontSize = 16.sp
            )
        }
        Box(modifier = Modifier.clip(CircleShape)
            .border(6.dp, White, CircleShape)
            .background(PrimaryGreen)
            .align(BiasAlignment(-1.22f, -1f))
        ) {
            Text(
                it.toString(),
                modifier = Modifier
                    .padding(14.dp),
                color = White,
                style =
                    TextStyle(
                        fontFamily = openSansFont,
                        fontWeight = FontWeight.SemiBold,
                    ),
                fontSize = 16.sp
            )
        }
    }
}

Screenshot 2025-02-07 at 8

Okay, if you noticed the green background bleeds outside from the border. This is not cool. And it turns out this is an existing bug from Google.