Exploring Shapes in Android Jetpack Compose (with Examples)

Jetpack Compose Shapes

Today, we will explore shapes in Android Jetpack Compose with the help of examples.

Prerequisites:

Jetpack Compose offers multiple shapes out of the box. They are:

  • RoundedCornerShape
  • CutCornerShape
  • RectangleShape
  • CircleShape

RoundedCornerShape:

It creates a rectangle shape with rounded corners.

For this article, let’s play with a box. We can set the box shape by using the modifier’s clip function.

@Composable
fun MyUI() {
    Box(
        modifier = Modifier
            .size(size = 100.dp)
            .clip(shape = RoundedCornerShape(size = 12.dp))
            .background(color = Color.Green)
    ) {
    }
}

Output:

RoundedCornerShape

We can use the method in different ways:

#1 fun RoundedCornerShape(size: Dp)

This is what we have done above. The size is applied to all the corners.

#2 fun RoundedCornerShape(size: Float)

It takes float instead of Dp.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = RoundedCornerShape(size = 30f))
        .background(color = Color.Green)
) {
}

Output:

jetpack compose rounded corners
#3 fun RoundedCornerShape(percent: Int)

We can set the corner radius in terms of percentage. If we pass 50, we get a circle.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = RoundedCornerShape(percent = 50))
        .background(color = Color.Green)
) {
}

Output:

Circle 50 percent
#4 fun RoundedCornerShape(corner: CornerSize)

It takes the CornerSize object and creates a rounded rectangle. The object can be obtained from CornerSize function. The function has multiple formats:

fun CornerSize(size: Dp): CornerSize
fun CornerSize(size: Float): CornerSize
fun CornerSize(percent: Int): CornerSize

Example:

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = RoundedCornerShape(corner = CornerSize(size = 30f)))
        .background(color = Color.Green)
) {
}

Output:

jetpack compose rounded corners
#5 fun RoundedCornerShape(topStart: Dp = 0.dp, topEnd: Dp = 0.dp, bottomEnd: Dp = 0.dp, bottomStart: Dp = 0.dp)

We can control the size of the individual corners.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(
            shape = RoundedCornerShape(
                topStart = 10.dp,
                topEnd = 20.dp,
                bottomEnd = 30.dp,
                bottomStart = 40.dp
            )
        )
        .background(color = Color.Green)
) {
}

Output:

RoundedCornerShape individual corners

Instead of Dp, it also accepts Float and Int (percentage):

fun RoundedCornerShape(topStart: Float = 0.0f, topEnd: Float = 0.0f, bottomEnd: Float = 0.0f, bottomStart: Float = 0.0f)
fun RoundedCornerShape(topStartPercent: Int = 0, topEndPercent: Int = 0, bottomEndPercent: Int = 0, bottomStartPercent: Int = 0)

CutCornerShape:

We can create a rectangle with cut corners.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = CutCornerShape(size = 20.dp))
        .background(color = Color.Green)
) {
}

Output:

CutCornerShape

Similar to RoundedCornerShape, CutCornerShape has multiple formats:

fun CutCornerShape(size: Dp)
fun CutCornerShape(size: Float)
fun CutCornerShape(percent: Int)
fun CutCornerShape(corner: CornerSize)
fun CutCornerShape(topStart: Dp = 0.dp, topEnd: Dp = 0.dp, bottomEnd: Dp = 0.dp, bottomStart: Dp = 0.dp)
fun CutCornerShape(topStart: Float = 0.0f, topEnd: Float = 0.0f, bottomEnd: Float = 0.0f, bottomStart: Float = 0.0f)
fun CutCornerShape(topStartPercent: Int = 0, topEndPercent: Int = 0, bottomEndPercent: Int = 0, bottomStartPercent: Int = 0)

RectangleShape:

It renders a plain rectangle. We do not have control over the corner sizes.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = RectangleShape)
        .background(color = Color.Green)
) {
}

Output:

RectangleShape

Note: By default, Box API renders a rectangle. So, in the above code, if you remove the clip method, you will get the same output.

CircleShape:

It creates a circle.

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(shape = CircleShape)
        .background(color = Color.Green)
) {
}

Output:

Circle 50 percent

Note: Internally, Jetpack Compose uses RoundedCornerShape to create CircleShape.

val CircleShape = RoundedCornerShape(50)

Instead of clip, we can also use other modifier functions like graphicsLayer, background, and border to render the shapes. Let’s create the above circle with these methods.

Using graphicsLayer:

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .graphicsLayer {
            clip = true // don't forget this
            shape = CircleShape
            // shadowElevation = 20f // you can also set elevation
        }
        .background(color = Color.Green)
) {
}

Using background:

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .background(color = Color.Green, shape = CircleShape)
) {
}

Using border:

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .border(
            width = 4.dp,
            color = Color.Green,
            shape = CircleShape
        )
) {
}

Output:

Border Shape Circle

On the android developers site, I found the following shape:

Top left corner

Let’s write the code for it:

Box(
    modifier = Modifier
        .size(size = 100.dp)
        .clip(
            shape = RoundedCornerShape(
                topStart = 40.dp,
                topEnd = 0.dp,
                bottomStart = 0.dp,
                bottomEnd = 0.dp
            )
        )
        .background(color = Color.Green)
) {
}

Look at these beautiful button styles made with rounded corners.

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

Leave a Comment