一.效果介绍
- 设置四个圆角的展现和隐藏
- 控件继承
ImageView
,可以使用ImageView
属性的src
和scaleType
- 设置角度的x和y值,x==y 圆角,x!=y 椭圆角
- 设置边框的颜色,边框宽度
通过src设置的图片会被裁剪,设置准确大小下scaleType会生效
先来看下效果吧
图片角度有两种方式BitmapShader
(图片着色器)和PorterDuffXfermode
(图像叠加覆盖的规则)
通过对画笔Paint
设置shader
和xfermode
来实现图片的圆角效果。
二.ShapeShaderImageView
BitmapShader实现的圆角图片
用Bitmap
的像素来作为图片或文字的填充。给Paint
设置shder
来使用
bitMapPaint.shader = bitmapShader
自定义属性:
属性名 | 属性类型 | 含义 | 默认值 |
---|---|---|---|
shiv_bg_color |
color/reference | 控件背景色 | Color.TRANSPARENT |
shiv_border_color |
color/reference | 边框颜色 | Color.WHITE |
shiv_border_width |
dimension/reference | 边框宽度 | 2dp |
shiv_radius |
dimension/reference | 圆角正方形的边长 | 5dp |
shiv_radius_x |
dimension/reference | 非圆角矩形的宽 | -1f |
shiv_radius_y |
dimension/reference | 非圆角矩形的长 | -1f(同时设置x,y大于0 才有效) |
shiv_top_left |
boolean | 左上是否有角度 | true |
shiv_top_right |
boolean | 右上是否有角度 | true |
shiv_bottom_left |
boolean | 左下是否有角度 | true |
shiv_bottom_right |
boolean | 右下是否有角度 | true |
onDraw()重写 :
删除spuer.onDraw(),实现自己的圆角逻辑
override fun onDraw(canvas: Canvas?) {
canvas?.drawColor(bgColor)
// BitmapShader实现
canvas?.save()
val bitmap = (drawable as BitmapDrawable).bitmap
val bitmapShader = BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
val matrix = setBitmapMatrixAndPath(width.toFloat(), height.toFloat(), bitmap)
bitmapShader.setLocalMatrix(matrix)
bitMapPaint.shader = bitmapShader
canvas?.drawPath(clipPath, bitMapPaint)
canvas?.restore()
borderPaint.style = Paint.Style.STROKE
canvas?.drawPath(borderPath, borderPaint)
if (!cornerTopLeftAble) {
borderPaint.style = Paint.Style.FILL
canvas?.drawRect(suppleRectF, borderPaint)
}
}
- 获取
bitmap
对象,将drawable
转为BitmapDrawable
获取bitmap
对象 - 声明
BitmapShader
对象,需要设置bitmap
,以及端点之外的图片延伸模式TileMode
, 图片的matrix
- 给
paint
设置shader
后,用canvas
的drawXXX
方法画出想要的图形,必须使用设置了shader
的paint
- 设置边框,给
borderPaint
设置颜色,填充模式和描边宽度即可正常绘制。 ShapeBitmaoshaderImageView
继承AppCompatImageView
,支持一些ImageView
的属性设置,例如src
,scaleType
等。
注意:在实际测试中发现,绘制边框时,首尾衔接不上,需要在开始的点的左上位置绘制一个边长为边框宽度的一半,颜色为边框颜色的正方形用于补充空白部分。修补代码及效果:
if (!cornerTopLeftAble) {
borderPaint.style = Paint.Style.FILL
canvas?.drawRect(suppleRectF, borderPaint)
}
修补前 | 修补后 |
---|---|
setBitmapMatrixAndPath(w,h,bitmap) 设置图片缩放,平移
根据ScaleType
的枚举值,进行图片的缩放,平移以达到ImageView
的ScaleType
效果。
/**
* 设置图片变化的matrix, 裁剪路径,边框路径
*/
private fun setBitmapMatrixAndPath(w: Float, h: Float, bitmap: Bitmap): Matrix {
// 图片变化的matrix
val matrix = Matrix()
// 图片缩放比例
val scaleX: Float
val scaleY: Float
// 缩放后的图片宽高
val bw: Float