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
相关产品推荐
相关产品推荐

