如何使用Android Canvas绘制带水平条纹的圆角矩形?
实现圆角条纹矩形的可行方案
方案一:裁剪圆角区域后循环绘制水平线
先利用裁剪路径限制绘制范围,再循环绘制水平线条,确保线条不会超出圆角区域:
override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val rect = RectF(50f, 50f, 300f, 400f) val cornerRadius = 20f val stripeSpacing = 30f // 条纹间距 val lineWidth = 2f // 绘制基础圆角矩形背景 val bgPaint = Paint().apply { color = Color.WHITE style = Paint.Style.FILL } canvas.drawRoundRect(rect, cornerRadius, cornerRadius, bgPaint) // 创建圆角裁剪路径,限制后续绘制范围 val clipPath = Path() clipPath.addRoundRect(rect, cornerRadius, cornerRadius, Path.Direction.CW) canvas.save() canvas.clipPath(clipPath) // 绘制水平条纹 val linePaint = Paint().apply { color = Color.GRAY strokeWidth = lineWidth style = Paint.Style.STROKE } var currentY = rect.top + stripeSpacing while (currentY < rect.bottom) { canvas.drawLine(rect.left, currentY, rect.right, currentY, linePaint) currentY += stripeSpacing } canvas.restore() // 恢复画布原始状态 }
方案二:用条纹纹理Shader绘制圆角矩形
先生成带有水平条纹的纹理,再通过Shader填充圆角矩形,这种方法无需单独处理线条裁剪:
override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val rect = RectF(50f, 50f, 300f, 400f) val cornerRadius = 20f val stripeHeight = 2f val stripeGap = 30f // 生成条纹纹理Bitmap val stripeBitmap = Bitmap.createBitmap( rect.width().toInt(), (stripeHeight + stripeGap).toInt(), Bitmap.Config.ARGB_8888 ) val stripeCanvas = Canvas(stripeBitmap) val stripePaint = Paint() // 绘制纹理底色 stripePaint.color = Color.WHITE stripeCanvas.drawRect(0f, 0f, stripeBitmap.width.toFloat(), stripeBitmap.height.toFloat(), stripePaint) // 绘制单条条纹 stripePaint.color = Color.GRAY stripeCanvas.drawRect(0f, 0f, stripeBitmap.width.toFloat(), stripeHeight, stripePaint) // 设置Shader到画笔 val fillPaint = Paint().apply { shader = BitmapShader(stripeBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT) } // 绘制带条纹纹理的圆角矩形 canvas.drawRoundRect(rect, cornerRadius, cornerRadius, fillPaint) // 回收Bitmap避免内存泄漏 stripeBitmap.recycle() }
直接用Path画线条失效的原因
直接用Path绘制线条时,若未通过裁剪限制绘制区域,线条会超出圆角矩形的边界,视觉上不符合“条纹矩形”的预期。上述两种方案都解决了这个问题:方案一通过裁剪路径约束线条范围,方案二则让纹理自动适配圆角区域。
内容的提问来源于stack exchange,提问作者Valdemiro Vieira
相关产品推荐
相关产品推荐

