我最近遇到了这个问题,并想出了一个不同的解决方案。恕我直言,最好的解决方案是创建您自己的Shape
实现并使用它来创建一个ShapeDrawable
.
下面是圆角矩形的简单实现,它允许您插入它的边框。
class InsetRoundRectShape(
private var radiusArray: FloatArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f),
private var inset: RectF = RectF()
): RectShape() {
private var innerRect: RectF = RectF()
private var path: Path = Path()
constructor(radius: Float, inset: RectF): this(floatArrayOf(radius, radius, radius, radius, radius, radius, radius, radius), inset)
constructor(radius: Float, inset: Float): this(radius, RectF(inset, inset, inset, inset))
init {
if (radiusArray.size < 8) {
throw ArrayIndexOutOfBoundsException("radius array must have >= 8 values")
}
}
override fun draw(canvas: Canvas, paint: Paint) {
canvas.drawPath(path, paint)
}
override fun getOutline(outline: Outline) {
super.getOutline(outline)
val radius = radiusArray[0]
if(radiusArray.any { it != radius }) {
outline.setConvexPath(path)
return
}
val r = rect()
outline.setRoundRect(ceil(r.left).toInt(), ceil(r.top).toInt(), floor(r.right).toInt(), floor(r.bottom).toInt(), radius)
}
override fun onResize(w: Float, h: Float) {
super.onResize(w, h)
val r = rect()
path.reset()
innerRect.set(r.left + inset.left, r.top + inset.top, r.right - inset.right, r.bottom - inset.bottom)
if(innerRect.width() <= w && innerRect.height() <= h) {
path.addRoundRect(innerRect, radiusArray, Path.Direction.CCW)
}
}
override fun clone(): InsetRoundRectShape {
val shape = super.clone() as InsetRoundRectShape
shape.radiusArray = radiusArray.clone()
shape.inset = RectF(inset)
shape.path = Path(path)
return shape
}
}
像这样创建 ShapeDrawable
//Inset has to be half of strokeWidth
ShapeDrawable(InsetRoundRectShape(10f, 4f)).apply {
this.paint.color = Color.BLUE
this.paint.style = Paint.Style.STROKE
this.paint.strokeWidth = 8.dp
this.invalidateSelf()
}