1

can anyone tell me how to create below shape in jetpack compose

enter image description here

Thank you in advance

Jayant Kumar
  • 775
  • 5
  • 12

2 Answers2

5

CustomShape inspired from https://juliensalvi.medium.com/custom-shape-with-jetpack-compose-1cb48a991d42

Its a extension of adding a paths with lines and arc.

For the transformation its just a rotation on y axis https://developer.android.com/jetpack/compose/graphics/draw/modifiers

A rounded border and a custom shape for background along with graphics layer that does rotation on y axis.

class CustomCardShape(private val radius: Float) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        return Outline.Generic(
            path = drawCardShape(size, radius)
        )
    }
}

The shape with path

fun drawCardShape(size: Size, cornerRadius: Float): Path {
    return Path().apply {
        reset()
        // Top left arc
        arcTo(
            rect = Rect(
                left = 0f,
                top = 0f,
                right = cornerRadius,
                bottom = cornerRadius
            ),
            startAngleDegrees = 180.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = size.width - cornerRadius, y = 0f)
        // Top right arc
        arcTo(
            rect = Rect(
                left = size.width - cornerRadius,
                top = 0f,
                right = size.width,
                bottom = cornerRadius
            ),
            startAngleDegrees = 270.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = size.width, y = size.height - cornerRadius)
        // Bottom right arc
        arcTo(
            rect = Rect(
                left = size.width - cornerRadius,
                top = size.height - cornerRadius,
                right = size.width,
                bottom = size.height
            ),
            startAngleDegrees = 0.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = cornerRadius, y = size.height)
        // Bottom left arc
        arcTo(
            rect = Rect(
                left = 0f,
                top = size.height - cornerRadius,
                right = cornerRadius,
                bottom = size.height
            ),
            startAngleDegrees = 90.0f,
            sweepAngleDegrees = 90.0f,
            forceMoveTo = false
        )
        lineTo(x = 0f, y = cornerRadius)
        close()
    }
}

The card composable

   Card(modifier = modifier
        .height(300.dp)
        .width(400.dp)
        .graphicsLayer {
            // pivot of where the rotation shud happen
            this.transformOrigin = TransformOrigin(0f, 0f)
            this.rotationY = 5f
        }.shadow(elevation = 4.dp, shape = CustomCardShape(80f),
            ambientColor  = Color(0xff2f5e9b),
            spotColor = Color(0xff2f5e9b)),
        border = BorderStroke(5.dp,Color(0xff5d6474)),
        backgroundColor = Color(0xff333d51),shape = CustomCardShape(80f)){

    }

Result

Card Composable with shape

The above might not be exactly like in the screen shot, however you can play with values to have it exactly like you want.

Raghunandan
  • 132,755
  • 26
  • 225
  • 256
2

You can also do like this , there is no need to create custom shape

@Composable
fun CustomCard() {

    Card(
        modifier = Modifier
            .height(300.dp)
            .width(600.dp)
            .padding(20.dp)
            .graphicsLayer {
                this.transformOrigin = TransformOrigin(0f, 0f)
                this.rotationY = 7f
            },
        border = BorderStroke(3.dp, Color(0xff5d6474)),
        backgroundColor = Color(0xff333d51), shape = RoundedCornerShape(80f)
    ) {

    }

}

In the graphics layer , just rotate the y-axis.

Jayant Kumar
  • 775
  • 5
  • 12