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

Jetpack Compose中如何绘制带折线末端的透明圆弧

Jetpack Compose 进度条透明圆弧空格实现方案

核心思路

直接通过分段绘制替代遮挡方案:将圆环划分为「进度渐变段」「透明空格段」「背景剩余段」,仅绘制进度段和背景的非空格部分,中间空格段完全不绘制,从根源避免遮挡带来的细竖线问题。(之前用drawArc画透明色无效是因为透明色不会覆盖已有内容;白色遮挡出现细竖线是绘制精度/抗锯齿的像素偏移问题)

实现代码

@Composable
fun CustomProgressBar(
    progress: Float, // 0f~1f,整体进度占比
    spaceAngle: Float = 20f, // 透明空格对应的角度
    strokeWidth: Dp = 8.dp,
    gradientColors: List<Color> = listOf(Color.Blue, Color.Purple),
    backgroundColor: Color = Color.Gray.copy(alpha = 0.3f),
    startAngle: Float = -90f // 进度条起始角度,-90f对应顶部开始
) {
    val strokeWidthPx = strokeWidth.toPx()
    Canvas(modifier = Modifier.size(200.dp)) {
        val center = Offset(size.width / 2, size.height / 2)
        val radius = min(size.width, size.height) / 2 - strokeWidthPx / 2
        val totalDrawAngle = 360f - spaceAngle // 扣除空格后的总可绘制角度
        val progressAngle = progress * totalDrawAngle // 当前进度对应的角度

        // 绘制背景:分两段跳过空格区域
        drawArc(
            color = backgroundColor,
            startAngle = startAngle,
            sweepAngle = progressAngle,
            useCenter = false,
            topLeft = Offset(center.x - radius, center.y - radius),
            size = Size(radius * 2, radius * 2),
            style = Stroke(width = strokeWidthPx, cap = StrokeCap.Round)
        )
        drawArc(
            color = backgroundColor,
            startAngle = startAngle + progressAngle + spaceAngle,
            sweepAngle = totalDrawAngle - progressAngle,
            useCenter = false,
            topLeft = Offset(center.x - radius, center.y - radius),
            size = Size(radius * 2, radius * 2),
            style = Stroke(width = strokeWidthPx, cap = StrokeCap.Round)
        )

        // 绘制渐变进度条
        val gradient = Brush.sweepGradient(colors = gradientColors, center = center)
        drawArc(
            brush = gradient,
            startAngle = startAngle,
            sweepAngle = progressAngle,
            useCenter = false,
            topLeft = Offset(center.x - radius, center.y - radius),
            size = Size(radius * 2, radius * 2),
            style = Stroke(width = strokeWidthPx, cap = StrokeCap.Round)
        )
    }
}

使用示例

@Composable
fun ProgressBarDemo() {
    Column(modifier = Modifier.fillMaxSize().padding(20.dp), horizontalAlignment = Alignment.CenterHorizontally) {
        CustomProgressBar(progress = 0.6f, spaceAngle = 30f)
    }
}

效果说明

  • 渐变进度到指定角度后,直接跳过空格角度绘制后续背景,中间无任何绘制内容,自然形成透明空格
  • 避免了遮挡方案的像素偏移问题,不会出现细竖线
  • 支持自定义起始角度、空格大小、渐变颜色、线条宽度等参数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 14:50:21