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

如何在Jetpack Compose中实现侧边半圆裁剪的自定义形状

Jetpack Compose 实现侧边顶部半圆裁剪的自定义Shape

问题背景

需要在Jetpack Compose中实现侧边靠近顶部位置带有半圆裁剪的自定义形状,但现有两段代码均未达到预期:

  • 初始代码把半圆裁剪放在了形状中部,不符合顶部位置的要求
  • 更新后的代码绘制路径逻辑有误,仍无法得到正确形状

可行实现示例

以下是可以实现侧边顶部半圆裁剪的自定义Shape代码:

fun topSideClippedShape(clipRadius: Float = 30f): Shape {
    return object : Shape {
        override fun createOutline(
            size: androidx.compose.ui.geometry.Size,
            layoutDirection: LayoutDirection,
            density: Density
        ): Outline {
            val path = Path().apply {
                // 起点:左上角
                moveTo(0f, 0f)
                
                // 左侧:从顶部向下到半圆裁剪的起始点
                lineTo(0f, clipRadius)
                // 左侧顶部半圆裁剪:绘制向左凹的半圆
                arcTo(
                    rect = Rect(
                        left = 0f,
                        top = 0f,
                        right = clipRadius * 2,
                        bottom = clipRadius * 2
                    ),
                    startAngleDegrees = 270f,
                    sweepAngleDegrees = 180f,
                    forceMoveTo = false
                )
                // 从半圆结束点向下到左下角
                lineTo(0f, size.height)
                
                // 底部:从左下角到右下角
                lineTo(size.width, size.height)
                
                // 右侧:从右下角向上到半圆裁剪的起始点
                lineTo(size.width, clipRadius)
                // 右侧顶部半圆裁剪:绘制向右凹的半圆
                arcTo(
                    rect = Rect(
                        left = size.width - clipRadius * 2,
                        top = 0f,
                        right = size.width,
                        bottom = clipRadius * 2
                    ),
                    startAngleDegrees = 90f,
                    sweepAngleDegrees = 180f,
                    forceMoveTo = false
                )
                // 从半圆结束点向上到右上角
                lineTo(size.width, 0f)
                
                // 闭合路径
                close()
            }
            return Outline.Generic(path)
        }
    }
}

绘制逻辑与数学原理

核心思路

要实现侧边顶部的半圆裁剪,本质是在形状的左右侧边顶部,绘制一个向内凹陷的半圆,需要明确半圆的边界矩形和角度参数:

  1. 半圆的边界矩形(Rect):

    • 左侧半圆:矩形左上角在(0,0),宽高均为clipRadius*2,这样半圆的圆心就是(clipRadius, clipRadius),半径为clipRadius,刚好贴合左侧顶部
    • 右侧半圆:矩形右上角在(size.width, 0),宽高均为clipRadius*2,圆心为(size.width - clipRadius, clipRadius),半径为clipRadius,刚好贴合右侧顶部
  2. arcTo参数解析:

    • startAngleDegrees:以3点钟方向为0度,顺时针为正方向
      • 左侧半圆从270度(12点钟方向)开始,对应侧边顶部的起始点
      • 右侧半圆从90度(6点钟方向)开始,对应侧边顶部的起始点
    • sweepAngleDegrees:设置为180度,刚好绘制一个完整的半圆
    • forceMoveTo:设为false,保证路径从之前的直线端点连续过渡到圆弧起点,避免出现断点
  3. 路径顺序:
    按照「左上→左半圆起点→左半圆→左下→右下→右半圆起点→右半圆→右上→闭合」的顺序绘制,确保路径连续闭合,形成完整的自定义形状。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 20:12:39