You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Jetpack Compose中实现卡片角落蓝色曲线设计

在Jetpack Compose中实现带角落蓝色曲线的卡片设计

要实现图中卡片的角落蓝色曲线效果,推荐两种简洁的实现方式,以下是具体代码和说明:

方式一:自定义Shape实现轮廓叠加

通过自定义Shape类定义带曲线的轮廓,再用两层Box叠加实现蓝色曲线露边的效果:

1. 定义自定义Shape

class CornerCurveShape(
    private val curveRadius: Dp
) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val radius = with(density) { curveRadius.toPx() }
        val path = Path().apply {
            // 左上角起点
            moveTo(0f, 0f)
            // 右上角绘制二次贝塞尔曲线
            lineTo(size.width - radius, 0f)
            quadraticBezierTo(
                x1 = size.width, y1 = 0f,
                x2 = size.width, y2 = radius
            )
            // 右下角直线
            lineTo(size.width, size.height)
            // 左下角绘制二次贝塞尔曲线
            lineTo(radius, size.height)
            quadraticBezierTo(
                x1 = 0f, y1 = size.height,
                x2 = 0f, y2 = size.height - radius
            )
            // 闭合路径
            close()
        }
        return Outline.Generic(path)
    }
}

2. 封装卡片组件

@Composable
fun CurveCornerCard(
    modifier: Modifier = Modifier,
    curveRadius: Dp = 24.dp,
    content: @Composable () -> Unit
) {
    Box(modifier = modifier.padding(curveRadius / 2)) {
        // 底层蓝色曲线背景层
        Box(
            modifier = Modifier
                .matchParentSize()
                .clip(CornerCurveShape(curveRadius))
                .background(Color.Blue)
        )
        // 上层白色内容卡片,通过内边距露出蓝色曲线
        Box(
            modifier = Modifier
                .matchParentSize()
                .padding(curveRadius / 2)
                .clip(RoundedCornerShape(curveRadius / 2))
                .background(Color.White)
                .padding(16.dp)
        ) {
            content()
        }
    }
}

3. 使用示例

@Preview
@Composable
fun PreviewCurveCard() {
    CurveCornerCard(curveRadius = 24.dp) {
        Column {
            Text("卡片标题", style = MaterialTheme.typography.headlineSmall)
            Spacer(modifier = Modifier.height(8.dp))
            Text("这里是卡片内容区域,可自由添加Compose组件", style = MaterialTheme.typography.bodyMedium)
        }
    }
}

方式二:Canvas直接绘制曲线

如果不需要整体轮廓裁剪,可直接在卡片背景上用Canvas绘制指定角落的蓝色曲线,更轻量灵活:

@Composable
fun CanvasCurveCard(
    modifier: Modifier = Modifier,
    curveRadius: Dp = 24.dp,
    content: @Composable () -> Unit
) {
    val radius = with(LocalDensity.current) { curveRadius.toPx() }
    Box(
        modifier = modifier
            .background(Color.White)
            .padding(16.dp)
            .drawBehind {
                // 绘制右上角蓝色曲线
                drawPath(
                    path = Path().apply {
                        moveTo(size.width - radius, 0f)
                        quadraticBezierTo(size.width, 0f, size.width, radius)
                        lineTo(size.width, 0f)
                        close()
                    },
                    color = Color.Blue
                )
                // 绘制左下角蓝色曲线
                drawPath(
                    path = Path().apply {
                        moveTo(0f, size.height - radius)
                        quadraticBezierTo(0f, size.height, radius, size.height)
                        lineTo(0f, size.height)
                        close()
                    },
                    color = Color.Blue
                )
            }
    ) {
        content()
    }
}

两种方式都可以实现需求,可根据实际场景选择:自定义Shape适合需要卡片整体特殊轮廓的场景,Canvas绘制适合仅局部添加曲线的场景。

内容的提问来源于stack exchange,提问作者Jay Jhaveri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:35:26