Jetpack Compose - 用图案绘制圆弧

dan*_*-eh 7 android kotlin android-jetpack-compose

我希望在 Jetpack Compose 的画布上绘制一条弧线,并带有对角条纹图案,如下图所示:

在此输入图像描述

我希望将其用作进度条,因此可以根据完成的百分比延长或缩短它。我目前有一个自定义圆形进度条,我在画布上为进度的空白部分绘制一个圆圈,然后为已完成的进度绘制一个圆弧。然而,设计想要实现一种超额状态,其中超额不是纯色,而是条纹图案。

现在我的解决方法就是绘制一个像这样充满条纹的矩形,然后剪掉角,然后在中间放一个白色圆圈,使其看起来像一个环,然后在顶部覆盖另一个进度条并删除纯色根据需要反转以露出条纹。然而,这并没有给我太多的自由来处理超额的问题。主要是弯曲的白色间隙变得很难完成,我只能做一个方角间隙。

所以我想用这种条纹图案创建弧线。

Mac*_*ęga 26

您可以使用 来实现这种条纹图案Brush.linearGradient
这里的技巧是使用“尖锐”​​的色标。因此,我们将为透明颜色应停止的位置和条纹颜色应开始的位置设置相同的位置。

这允许创建一个有角度的线性渐变,在小正方形上看起来像这样:

在此输入图像描述

但当在更大的区域使用时,TileMode.Repeated它会很好地“循环”成所需的条纹图案:

在此输入图像描述

以下是如何实现此类梯度的示例:

private fun Density.createStripeBrush(
    stripeColor: Color,
    stripeWidth: Dp,
    stripeToGapRatio: Float
): Brush {
    val stripeWidthPx = stripeWidth.toPx()
    val stripeGapWidthPx = stripeWidthPx / stripeToGapRatio
    val brushSizePx = stripeGapWidthPx + stripeWidthPx
    val stripeStart = stripeGapWidthPx / brushSizePx

    return Brush.linearGradient(
        stripeStart to Color.Transparent,
        stripeStart to stripeColor,
        start = Offset(0f, 0f),
        end = Offset(brushSizePx, brushSizePx),
        tileMode = TileMode.Repeated
    )
}
Run Code Online (Sandbox Code Playgroud)

有了Brush这样的东西,我们就可以将它用于任何绘图操作。
例如,这里它用于Modifier.drawWithCacheto drawArc,因此您可以完全自由地控制笔划样式等:

.drawWithCache {
    val brush = createStripeBrush(
        stripeColor = Color.Blue,
        stripeWidth = stripeWidth,
        stripeToGapRatio = 1.8f
    )
    onDrawWithContent {
        drawArc(
            brush = brush,
            startAngle = 0f,
            sweepAngle = -90f,
            useCenter = false,
            style = Stroke(width = strokeWidth, cap = StrokeCap.Round)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述