繁体   English   中英

Jetpack Compose - 用图案绘制弧线

[英]Jetpack Compose - Draw Arc with Pattern

我希望在 Jetpack Compose 中的 canvas 上绘制一条弧线,并带有如下图所示的斜条纹图案:

在此处输入图像描述

我希望将其用作进度条,因此可以根据完成的百分比对其进行扩展或缩短。 我目前有一个自定义的圆形进度条,我在 canvas 上为进度的空白部分画一个圆圈,然后为完成的进度画一个弧线。 然而,设计想要实现一个超额 state,其中,而不是纯色,超额具有这种条纹图案。

现在我的解决方法就是画一个像这样填充条纹的矩形,然后剪掉角落,然后在中间放一个白色圆圈,让它看起来像一个环,然后在顶部覆盖另一个进度条并去除纯色根据需要反向显示条纹。 然而,这并没有给我太多的自由来处理超龄。 主要是弯曲的白色间隙变得难以完成,我只能做一个方形的角间隙。

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

您可以使用Brush.linearGradient实现这种条纹图案。
这里的诀窍是使用“锐利”的色标。 所以我们将设置相同的 position 用于透明颜色应该停止的位置和条纹颜色应该开始的位置。

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

在此处输入图像描述

但是当使用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
    )
}

拥有这样的Brush ,我们可以将它用于任何绘图操作。
例如这里它在Modifier.drawWithCache中用于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)
        )
    }
}

在此处输入图像描述

您的解决方案看起来正确。 要获得圆形间隙,请尝试使用图像创建该间隙并将其围绕圆圈旋转。 间隙图像的两端都是圆形的。 图像的内部是白色的,但外部是透明的 - 本质上是 png 或可能是 svg。

或者,创建一个图像,其中有一个白色圆圈(您已经在使用的大圆圈),其边缘有一个延伸的间隙,然后只需旋转圆圈以使间隙出现在它应该出现的位置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM