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

如何在Android Jetpack Compose中实现类似圆形进度条的矩形边框进度条

实现矩形边框进度指示器(类似圆形进度条样式)

要实现矩形边框的进度指示器,你可以通过Compose的Canvas自定义绘制,以下是完整实现方案:

自定义进度指示器组件

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.StrokeCap
import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

@Composable
fun RectangularBorderProgressIndicator(
    progress: Float, // 进度值,范围0f-1f
    strokeWidth: Dp = 10.dp,
    color: Color = MaterialTheme.colorScheme.primary,
    backgroundColor: Color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f),
    modifier: Modifier = Modifier
) {
    Canvas(modifier = modifier) {
        val strokeWidthPx = strokeWidth.toPx()
        val halfStroke = strokeWidthPx / 2
        // 绘制区域:减去边框宽度的一半,避免边框超出容器
        val drawSize = Size(
            width = size.width - strokeWidthPx,
            height = size.height - strokeWidthPx
        )
        val topLeft = Offset(halfStroke, halfStroke)
        val bottomRight = Offset(topLeft.x + drawSize.width, topLeft.y + drawSize.height)

        // 绘制背景边框
        drawRect(
            color = backgroundColor,
            topLeft = topLeft,
            size = drawSize,
            style = Stroke(width = strokeWidthPx)
        )

        // 计算总周长和进度对应的长度
        val perimeter = 2 * (drawSize.width + drawSize.height)
        val progressLength = perimeter * progress.coerceIn(0f, 1f)

        // 构建进度路径
        val path = Path().apply {
            moveTo(topLeft.x, topLeft.y)
            var remainingLength = progressLength

            // 绘制顶部边
            val topEdgeLength = drawSize.width
            if (remainingLength <= topEdgeLength) {
                lineTo(topLeft.x + remainingLength, topLeft.y)
                remainingLength = 0f
            } else {
                lineTo(bottomRight.x, topLeft.y)
                remainingLength -= topEdgeLength
            }

            // 绘制右侧边
            val rightEdgeLength = drawSize.height
            if (remainingLength > 0 && remainingLength <= rightEdgeLength) {
                lineTo(bottomRight.x, topLeft.y + remainingLength)
                remainingLength = 0f
            } else if (remainingLength > 0) {
                lineTo(bottomRight.x, bottomRight.y)
                remainingLength -= rightEdgeLength
            }

            // 绘制底部边
            val bottomEdgeLength = drawSize.width
            if (remainingLength > 0 && remainingLength <= bottomEdgeLength) {
                lineTo(bottomRight.x - remainingLength, bottomRight.y)
                remainingLength = 0f
            } else if (remainingLength > 0) {
                lineTo(topLeft.x, bottomRight.y)
                remainingLength -= bottomEdgeLength
            }

            // 绘制左侧边
            val leftEdgeLength = drawSize.height
            if (remainingLength > 0 && remainingLength <= leftEdgeLength) {
                lineTo(topLeft.x, bottomRight.y - remainingLength)
            }
        }

        // 绘制进度边框
        drawPath(
            path = path,
            color = color,
            style = Stroke(
                width = strokeWidthPx,
                cap = StrokeCap.Round // 可选:设置端点为圆角,和CircularProgressIndicator风格统一
            )
        )
    }
}

使用示例

替换你原来的CircularProgressIndicator,直接调用自定义组件即可:

RectangularBorderProgressIndicator(
    progress = 0.75f, // 75%进度
    strokeWidth = 10.dp,
    color = Color.Red,
    modifier = Modifier.size(200.dp)
)

关键说明

  • 背景边框:先绘制一层半透明的完整矩形边框,作为未完成部分的视觉参考
  • 进度计算:通过矩形周长乘以进度值,确定需要绘制的边框长度,再分四个边依次绘制
  • StrokeCap.Round:可选启用,让边框端点和圆形进度条风格保持一致
  • 参数兼容:保留了和CircularProgressIndicator类似的参数(progress、strokeWidth、color),方便替换

内容的提问来源于stack exchange,提问作者Mohammed Ragab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 10:20:26