簡體   English   中英

Jetpack 用點圓組成畫弧

[英]Jetpack Compose Draw Arc with Dot Circle

我希望在 Jetpack Compose 中的 canvas 上畫一條弧線,在進度邊緣有一個小圓圈,如下圖所示:

在此處輸入圖像描述

我找到了如何用弧形 canvas 繪制進度條,但還不知道如何繪制與弧線邊緣匹配的圓。 這是我的進度代碼:

@Composable
fun ComposeCircularProgressBar(
    modifier: Modifier = Modifier,
    percentage: Float,
    fillColor: Color,
    backgroundColor: Color,
    strokeWidth: Dp
) {
    Canvas(
        modifier = modifier
            .padding(strokeWidth / 2)
    ) {
        // Background Line
        drawArc(
            color = backgroundColor,
            135f,
            270f,
            false,
            style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Butt)
        )
        // Fill Line
        drawArc(
            color = fillColor,
            135f,
            270f * percentage,
            false,
            style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round)
        )
    }
}

注意:現在我知道用Canvas.drawCircle(offset = Offset)繪制那個圓,但我還不知道如何計算Offset(x,y)以匹配進度的邊緣。

下面的這段代碼將根據您提供的百分比生成帶有圓點的弧線。 你確實得到了大部分正確的部分,它只是解決數學方程以找到圓上的點。

我假設圓的半徑為小部件的高度/2

由於我們沒有畫完整的圓,所以起始角為 140 度,最大掃角為 260 度。 (我通過點擊和試用找到了這個,所以它看起來和你的圖像一樣接近)

現在要繪制白色的小圓圈,中心也就是偏移量必須在 (x,y) 處,其中 x 和 y 由公式給出

x = 半徑 * sin(以弧度表示的角度) y = 半徑 * cos(以弧度表示的角度)

@Composable
fun ComposeCircularProgressBar(
    modifier: Modifier = Modifier,
    percentage: Float,
    fillColor: Color,
    backgroundColor: Color,
    strokeWidth: Dp
) {
    Canvas(
        modifier = modifier
            .size(150.dp)
            .padding(10.dp)
    ) {
        // Background Line
        drawArc(
            color = backgroundColor,
            140f,
            260f,
            false,
            style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
            size = Size(size.width, size.height)
        )

        drawArc(
            color = fillColor,
            140f,
             percentage * 260f,
            false,
            style = Stroke(strokeWidth.toPx(), cap = StrokeCap.Round),
            size = Size(size.width, size.height)
        )


        var angleInDegrees = (percentage * 260.0) + 50.0
        var radius = (size.height / 2)
        var x = -(radius * sin(Math.toRadians(angleInDegrees))).toFloat() + (size.width / 2)
        var y = (radius * cos(Math.toRadians(angleInDegrees))).toFloat() + (size.height / 2)

        drawCircle(
            color = Color.White,
            radius = 5f,
            center = Offset(x,  y)
        )
    }
}

這是我嘗試過的一些示例

80% 進度

@Preview
@Composable
fun PreviewPorgressBar() {
    ComposeCircularProgressBar(
        percentage = 0.80f,
        fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
        backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
        strokeWidth = 10.dp
    )
}

45% 進展

@Preview
@Composable
fun PreviewPorgressBar() {
    ComposeCircularProgressBar(
        percentage = 0.45f,
        fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
        backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
        strokeWidth = 10.dp
    )
}

100% 進展

@Preview
@Composable
fun PreviewPorgressBar() {
    ComposeCircularProgressBar(
        percentage = 1f,
        fillColor = Color(android.graphics.Color.parseColor("#4DB6AC")),
        backgroundColor = Color(android.graphics.Color.parseColor("#90A4AE")),
        strokeWidth = 10.dp
    )
}

[更新] 如果您對分步教程感興趣,可以在此處閱讀: https://www.droidchef.dev/custom-progress-with-jetpack-compose-tutorial/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM