项目中使用到一个imageview上面是两个圆角,下面是两个直角,如图
网上找了一波类似的控件,找到了这个
public class OvalImageView extends ImageView {
/*圆角的半径,依次为左上角xy半径,右上角,右下角,左下角*/
private float[] rids = {10.0f, 10.0f, 10.0f, 10.0f, 0.0f, 0.0f, 0.0f, 0.0f,};
public OvalImageView(Context context) {
super(context);
}
public OvalImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public OvalImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 画图
* by Hankkin at:2015-08-30 21:15:53
*
* @param canvas
*/
protected void onDraw(Canvas canvas) {
Path path = new Path();
int w = this.getWidth();
int h = this.getHeight();
/*向路径中添加圆角矩形。radii数组定义圆角矩形的四个圆角的x,y半径。radii长度必须为8*/
path.addRoundRect(new RectF(0, 0, w, h), rids, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
但是使用过程中会出现有点卡顿的问题,采用这种裁剪的方式性能显然不是很好
然后我又想到glide可以显示圆角,并且项目中集成了glide,那就用glide来试试
但是glide4.x和3.x使用的方式很不一样,导致centerCrop()和transform并不能共存
最开始直接使用transform继承BitmapTransformation
class GlideRoundedCornersTransform extends BitmapTransformation {}
显然这样是用不了的
然后查阅了下资料
需要继承CenterCrop
class GlideRoundedCornersTransform extends CenterCrop {}
并且下面重写方法的这个位置很关键
就是先调用super的CenterCrop处理,得到的结果再在自己的roundCrop里处理
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Bitmap transform = super.transform(pool, toTransform, outWidth, outHeight);
return roundCrop(pool, transform);
}
这样设置进去就可以了
val options = RequestOptions()
options.optionalTransform(GlideRoundedCornersTransform(5f, GlideRoundedCornersTransform.CornerType.TOP))
Glide.with(mContext).load(url).apply(options).into(imageView)
贴下transform代码,完美显示
public class GlideRoundedCornersTransform extends CenterCrop {
private float mRadius;
private CornerType mCornerType;
private static final int VERSION = 1;
private static final String ID = BuildConfig.APPLICATION_ID+"GlideRoundedCornersTransform." + VERSION;
private static final byte[] ID_BYTES = ID.getBytes(CHARSET);
public enum CornerType {
ALL,
TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,
TOP, BOTTOM, LEFT, RIGHT,
TOP_LEFT_BOTTOM_RIGHT,
TOP_RIGHT_BOTTOM_LEFT,
TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT,
TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT,
}
public GlideRoundedCornersTransform(float radius, CornerType cornerType) {
super();
mRadius = UIUtils.dp2px(radius);//dp ->px
mCornerType = cornerType;
}
@Override
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
Bitmap transform = super.transform(pool, toTransform, outWidth, outHeight);
return roundCrop(pool, transform);
}
private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
if (source == null) {
return null;
}
int width = source.getWidth();
int height = source.getHeight();
Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
if (result == null) {
result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config
.ARGB_8888);
}
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader
.TileMode.CLAMP));
paint.setAntiAlias(true);
Path path = new Path();
drawRoundRect(canvas, paint, path, width, height);
return result;
}
private void drawRoundRect(Canvas canvas, Paint paint, Path path, int width, int height) {
float[] rids ;
switch (mCornerType) {
case ALL:
rids = new float[]{mRadius,mRadius,mRadius,mRadius,mRadius,mRadius,mRadius,mRadius};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_LEFT:
rids = new float[]{mRadius,mRadius,0.0f,0.0f,0.0f,0.0f,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_RIGHT:
rids = new float[]{0.0f,0.0f,mRadius,mRadius,0.0f,0.0f,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case BOTTOM_RIGHT:
rids = new float[]{0.0f,0.0f,0.0f,0.0f,mRadius,mRadius,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case BOTTOM_LEFT:
rids = new float[]{0.0f,0.0f,0.0f,0.0f,0.0f,0.0f,mRadius,mRadius};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP:
rids = new float[]{mRadius,mRadius,mRadius,mRadius,0.0f,0.0f,0.0f,0.0f};
drawPath(rids,canvas, paint, path,width, height);
break;
case BOTTOM:
rids = new float[]{0.0f,0.0f,0.0f,0.0f,mRadius,mRadius,mRadius,mRadius};
drawPath(rids,canvas, paint, path, width, height);
break;
case LEFT:
rids = new float[]{mRadius,mRadius,0.0f,0.0f,0.0f,0.0f,mRadius,mRadius};
drawPath(rids,canvas, paint, path, width, height);
break;
case RIGHT:
rids = new float[]{0.0f,0.0f,mRadius,mRadius,mRadius,mRadius,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_LEFT_BOTTOM_RIGHT:
rids = new float[]{mRadius,mRadius,0.0f,0.0f,mRadius,mRadius,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_RIGHT_BOTTOM_LEFT:
rids = new float[]{0.0f,0.0f,mRadius,mRadius,0.0f,0.0f,mRadius,mRadius};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_LEFT_TOP_RIGHT_BOTTOM_RIGHT:
rids = new float[]{mRadius,mRadius,mRadius,mRadius,mRadius,mRadius,0.0f,0.0f};
drawPath(rids,canvas, paint, path, width, height);
break;
case TOP_RIGHT_BOTTOM_RIGHT_BOTTOM_LEFT:
rids = new float[]{0.0f,0.0f,mRadius,mRadius,mRadius,mRadius,mRadius,mRadius};
drawPath(rids,canvas, paint, path,width, height);
break;
default:
throw new RuntimeException("RoundedCorners type not belong to CornerType");
}
}
/**@param rids 圆角的半径,依次为左上角xy半径,右上角,右下角,左下角*/
private void drawPath(float[] rids,Canvas canvas,Paint paint,Path path, int width, int height) {
path.addRoundRect(new RectF(0, 0, width, height), rids, Path.Direction.CW);
// canvas.clipPath(path);
canvas.drawPath(path,paint);
}
@Override
public boolean equals(Object o) {
return o instanceof GlideRoundedCornersTransform;
}
@Override
public int hashCode() {
return ID.hashCode();
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
messageDigest.update(ID_BYTES);
}
}