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

Jetpack Compose如何在Canvas上绘制带斜纹图案的圆弧用作环形进度条超额状态

实现Jetpack Compose Canvas斜纹图案圆弧方案

核心实现逻辑是通过可平铺的ImageShader作为笔刷直接绘制圆弧,避免了多层裁剪叠加的复杂度,和原有纯色圆弧绘制逻辑完全兼容,可直接适配百分比长度调整需求

步骤1:预生成斜纹图案Bitmap

首先生成最小可重复单元的斜纹Bitmap,后续交给Shader自动平铺即可,Bitmap只需要生成一次,避免重组重复计算:

val stripeBitmap by remember {
    val unitSize = 40 // 单个斜纹单元尺寸,单位px,可按需调整
    val bitmap = Bitmap.createBitmap(unitSize, unitSize, Bitmap.Config.ARGB_8888)
    val canvas = android.graphics.Canvas(bitmap)
    val paint = android.graphics.Paint().apply {
        color = Color(0xFFE53935).toArgb() // 斜纹自定义颜色
        strokeWidth = 8f // 斜纹自定义宽度
        isAntiAlias = true
    }
    // 绘制45度斜纹,铺满单个单元
    canvas.drawLine(0f, unitSize.toFloat(), unitSize.toFloat(), 0f, paint)
    canvas.drawLine(-unitSize/2f, unitSize/2f, unitSize/2f, -unitSize/2f, paint)
    canvas.drawLine(unitSize/2f, unitSize*1.5f, unitSize*1.5f, unitSize/2f, paint)
    mutableStateOf(bitmap)
}

步骤2:创建平铺斜纹笔刷

用ImageShader封装Bitmap,设置XY轴重复平铺模式,生成可以直接给Canvas绘制用的Brush:

val stripeBrush by remember(stripeBitmap) {
    derivedStateOf {
        ShaderBrush(
            ImageShader(
                bitmap = stripeBitmap.asImageBitmap(),
                tileModeX = TileMode.Repeated,
                tileModeY = TileMode.Repeated
            )
        )
    }
}

步骤3:绘制斜纹圆弧

和原有绘制纯色圆弧的逻辑完全一致,直接把笔刷替换成上面生成的斜纹Brush即可,扫过角度按超额百分比计算:

Canvas(modifier = Modifier.size(200.dp)) {
    val ringStrokeWidth = 24.dp.toPx()
    val ringRadius = size.minDimension / 2 - ringStrokeWidth / 2
    // 绘制背景空白圆环
    drawCircle(
        color = Color(0xFFF0F0F0),
        radius = ringRadius,
        style = Stroke(ringStrokeWidth)
    )
    // 绘制正常进度纯色圆弧
    val normalProgress = 0.8f // 正常进度80%
    val normalSweepAngle = 360 * normalProgress
    drawArc(
        color = Color(0xFF2196F3),
        startAngle = -90f,
        sweepAngle = normalSweepAngle,
        useCenter = false,
        style = Stroke(ringStrokeWidth, cap = StrokeCap.Round)
    )
    // 绘制超额进度斜纹圆弧
    val excessProgress = 0.25f // 超额进度25%
    val excessSweepAngle = 360 * excessProgress
    drawArc(
        brush = stripeBrush,
        startAngle = -90f + normalSweepAngle,
        sweepAngle = excessSweepAngle,
        useCenter = false,
        style = Stroke(ringStrokeWidth, cap = StrokeCap.Round)
    )
}

自定义优化点

  • 调整斜纹的角度、颜色、间距,仅需要修改Bitmap生成阶段的绘制参数即可
  • 需要斜纹角度适配圆弧弧度时,可给ImageShader设置本地变换矩阵,调用setLocalMatrix传入旋转/平移矩阵即可
  • 性能上和纯色圆弧绘制开销基本一致,无额外裁剪、图层叠加的性能损耗

内容的提问来源于stack exchange,提问作者daniel-eh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 20:06:02