Home > Software design >  How to draw a curved border on the bottom of a button in Android Compose
How to draw a curved border on the bottom of a button in Android Compose

Time:11-05

I am trying to replicate a button with a drop shadow that is filled and I have been having trouble setting a bottom border to match my needs.

What I am trying to achieve: Button UI Design

What I have tried so far:

fun Modifier.bottomBorder(strokeWidth: Dp, color: Color, cornerRadiusDp: Dp) = composed(
    factory = {
        val density = LocalDensity.current
        val strokeWidthPx = density.run { strokeWidth.toPx() }
        val cornerRadiusPx = density.run { cornerRadiusDp.toPx() }

        Modifier.drawBehind {
            val width = size.width
            val height = size.height

            drawArc(
                color = color,
                startAngle = 90f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset(x = 0f, y = height - cornerRadiusPx * 1.2f),
                size = Size(width/2, height/2),
                style = Stroke(width = strokeWidthPx, cap = StrokeCap.Round),
            )

            drawLine(
                color = color,
                start = Offset(x = cornerRadiusPx, y = height),
                end = Offset(x = width - cornerRadiusPx, y = height),
                strokeWidth = strokeWidthPx
            )

            drawArc(
                color = color,
                startAngle = 0f,
                sweepAngle = 90f,
                useCenter = false,
                topLeft = Offset(x = width - cornerRadiusPx * 2, y = height - cornerRadiusPx * 2),
                size = Size(cornerRadiusPx * 2, cornerRadiusPx * 2),
                style = Stroke(width = strokeWidthPx, cap = StrokeCap.Round)
            )

        }
    }
)

The result of that looks like this:

enter image description here

I am not sure how to get the corners to be rounded instead of pointed at the bottom. Any help would be appreciated.

CodePudding user response:

enter image description here

You can draw roundedRectangles inside a Modifier

fun Modifier.drawBorder(
    backgroundColor: Color,
    foregroundColor: Color,
    strokeWidth: Dp = 2.dp,
    cornerRadius: Dp = 16.dp,
    bottomStroke: Dp = 10.dp
) = this.then(
    Modifier.drawBehind {
        val strokeWidthPx = strokeWidth.toPx()
        val bottomStrokeWidthPx = bottomStroke.toPx()
        val cornerRadiusPx = cornerRadius.toPx()

        drawRoundRect(
            color = backgroundColor,
            cornerRadius = CornerRadius(cornerRadiusPx * 1.2f, cornerRadiusPx * 1.2f)
        )

        drawRoundRect(
            color = foregroundColor,
            cornerRadius = CornerRadius(cornerRadiusPx, cornerRadiusPx),
            topLeft = Offset(strokeWidthPx, strokeWidthPx),
            size = Size(size.width - strokeWidthPx * 2, size.height - bottomStrokeWidthPx)
        )
    }
)

Demo

@Preview
@Composable
private fun BorderTest() {
    Column(
        modifier = Modifier.padding(16.dp)
    ) {
        Box(
            modifier = Modifier
                .drawBorder(
                    backgroundColor = Color.Black,
                    foregroundColor = Color.White
                )
                .height(60.dp).width(100.dp),
            contentAlignment = Alignment.Center
        ) {
            Text("A Button")
        }
    }
}
  • Related