字面意思,view最外层的圆角,跟view里面某个区域的圆角 在有些场景下,会经常使用自定义view去绘制图标,还有各种下载状态,角标之类的 此时,有个需求需要你在基础上绘制一个带圆角的边框,基于这种前提下,外层的圆角显然不满足需求了
先来说下外圆角,方式很多种,也是常用的方式,xml,shape,imageview,cardview,图片框架等
自定义view可以使用 Outline 方式
clipToOutline = true
outlineProvider = object : ViewOutlineProvider() {
override fun getOutline(view: View?, outline: Outline?) {
radiusRectF.set(
borderMargin.toInt(),
borderMargin.toInt(),
width - borderMargin.toInt(),
height - borderMargin.toInt()
)
outline?.setRoundRect(radiusRectF, corner)
}
}
但是你会发现这种方式只能达到外层圆角,如果外面有个边框,边框里面的图片就没圆角处理了 这种时候要么两种常用的方案 一种是使用纯xml布局,内嵌view,单独给某个view去处理圆角,这种相对简单,但是对于有些场景略显麻烦 第二种是使用自定义view绘制,在绘制过程中单独处理圆角
private val mode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT)
private val mPaint = Paint().apply {
isAntiAlias = true
xfermode = mode
}
private val mPath = Path()
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
mPath.reset()
//画布剪裁成圆角
val p = Path()
p.addRoundRect(
iconRectF,
floatArrayOf(corner, corner, corner, corner, corner, corner, corner, corner),
Path.Direction.CCW
)
mPath.addRect(iconRectF, Path.Direction.CCW)
mPath.op(p, Path.Op.DIFFERENCE)
}
override fun onDraw(canvas: Canvas) {
icon?.let {
it.bounds = iconRectF.toRect()
it.draw(canvas)
}
canvas.drawPath(mPath, mPaint)
}
这样就轻松做到了内外圆角单独处理,而且每个角的圆角都能自定义,比较容易扩展