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

如何在Jetpack Compose中绘制自定义形状的Surface组件

在Jetpack Compose中实现带左上角缺口的自定义Surface

直接用两个Surface拼接会因为各自的阴影(elevation)导致视觉断层,正确的做法是自定义Shape,让整个Surface成为一个连续的形状,这样阴影会沿着完整轮廓生成。

步骤1:实现自定义Shape类

根据你需要的左上角缺口样式,用Path绘制完整的形状轮廓。以下是直角缺口的实现示例:

class CustomTopLeftCutShape(private val cutSize: Dp) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val cutPx = with(density) { cutSize.toPx() }
        val path = Path().apply {
            // 按顺时针顺序绘制轮廓
            moveTo(size.width, 0f)
            lineTo(size.width, size.height)
            lineTo(0f, size.height)
            lineTo(0f, cutPx)
            lineTo(cutPx, cutPx)
            lineTo(cutPx, 0f)
            close()
        }
        return Outline.Generic(path)
    }
}

如果需要圆角缺口,可以修改Path逻辑,添加圆弧:

class CustomTopLeftRoundedCutShape(
    private val cutSize: Dp,
    private val cornerRadius: Dp
) : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val cutPx = with(density) { cutSize.toPx() }
        val cornerRadiusPx = with(density) { cornerRadius.toPx() }
        val path = Path().apply {
            moveTo(size.width, 0f)
            lineTo(size.width, size.height)
            lineTo(0f, size.height)
            lineTo(0f, cutPx)
            // 绘制圆角圆弧
            arcTo(
                rect = Rect(0f, 0f, cutPx, cutPx),
                startAngle = 180f,
                sweepAngle = 90f,
                forceMoveTo = false
            )
            lineTo(cutPx, 0f)
            close()
        }
        return Outline.Generic(path)
    }
}

步骤2:在Surface中使用自定义Shape

直接将自定义Shape传给Surface的shape参数,同时设置elevation即可:

Surface(
    shape = CustomTopLeftCutShape(cutSize = 24.dp),
    elevation = 8.dp,
    modifier = Modifier
        .size(200.dp, 150.dp)
        .padding(16.dp),
    color = MaterialTheme.colorScheme.surface
) {
    // 内部内容,按需添加
    Text(
        text = "自定义形状示例",
        modifier = Modifier.padding(16.dp),
        style = MaterialTheme.typography.bodyLarge
    )
}

关键说明

  • 自定义Shape是一个整体,elevation的阴影会沿着完整的轮廓生成,不会出现拼接断层。
  • 通过调整cutSize参数可以控制缺口的大小,修改Path的绘制逻辑可以实现任意样式的左上角造型。

内容的提问来源于stack exchange,提问作者Martim Gouveia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 01:41:05