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

Android Jetpack Compose:drawArc如何自定义StrokeCap端点圆角半径?

Jetpack Compose Canvas 自定义速度表弧形端点圆角方案

Jetpack Compose 里的 StrokeCap.Round 是固定用线条宽度的一半当圆角半径的,没有内置参数直接修改这个半径。要实现更小的平滑端点,给你两个实用方案:

方案1:描边宽度调整+画布缩放

思路是先用更细的描边画出带Round端点的弧形,再把画布放大到目标尺寸,这样端点的圆角会按比例缩小,刚好符合需求。

示例代码:

Canvas(modifier = Modifier.size(200.dp)) {
    val targetStrokeWidth = 20.dp.toPx()
    val scaledStrokeWidth = targetStrokeWidth / 2 // 用一半宽度绘制基础弧形
    val scaleFactor = 2f // 对应缩放倍数,和宽度比例对应

    save()
    // 以画布中心为基准缩放,避免位置偏移
    scale(scaleFactor, scaleFactor, center = center)
    drawArc(
        brush = Brush.verticalGradient(listOf(Color.Blue, Color.Cyan)),
        startAngle = 135f,
        sweepAngle = 270f,
        useCenter = false,
        topLeft = Offset(20.dp.toPx(), 20.dp.toPx()),
        size = Size(160.dp.toPx(), 160.dp.toPx()),
        style = Stroke(
            width = scaledStrokeWidth,
            cap = StrokeCap.Round
        )
    )
    restore()
}

方案2:手动绘制端点圆角

如果需要精准控制圆角大小,可以先画不带端点的弧形(用StrokeCap.Butt),然后在两个端点位置手动画小圆形,模拟自定义半径的圆角。

示例代码:

Canvas(modifier = Modifier.size(200.dp)) {
    val strokeWidth = 20.dp.toPx()
    val customCapRadius = 5.dp.toPx() // 这里直接设置你想要的圆角半径
    val arcRect = Rect(
        left = 20.dp.toPx(),
        top = 20.dp.toPx(),
        right = 180.dp.toPx(),
        bottom = 180.dp.toPx()
    )
    val arcCenter = arcRect.center
    val arcRadius = arcRect.width / 2

    // 第一步:绘制无端点的基础弧形
    drawArc(
        brush = Brush.verticalGradient(listOf(Color.Blue, Color.Cyan)),
        startAngle = 135f,
        sweepAngle = 270f,
        useCenter = false,
        topLeft = arcRect.topLeft,
        size = arcRect.size,
        style = Stroke(
            width = strokeWidth,
            cap = StrokeCap.Butt
        )
    )

    // 辅助函数:根据角度计算弧形端点坐标
    fun getArcEndPoint(angleDeg: Float): Offset {
        val angleRad = Math.toRadians(angleDeg.toDouble()).toFloat()
        return Offset(
            arcCenter.x + arcRadius * cos(angleRad),
            arcCenter.y + arcRadius * sin(angleRad)
        )
    }
    val startPoint = getArcEndPoint(135f)
    val endPoint = getArcEndPoint(135f + 270f)

    // 第二步:手动绘制两个端点的圆角
    drawCircle(
        brush = Brush.verticalGradient(listOf(Color.Blue, Color.Cyan)),
        center = startPoint,
        radius = customCapRadius
    )
    drawCircle(
        brush = Brush.verticalGradient(listOf(Color.Cyan, Color.Blue)),
        center = endPoint,
        radius = customCapRadius
    )
}

注意:手动绘制时要保证端点的渐变方向和弧形一致,不然会出现颜色衔接的断层问题。

内容的提问来源于stack exchange,提问作者tobi.g

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 04:00:06