支持圆形、圆角(默认4边圆角,支持自定义各个圆角radius)图片。
先建个类RoundImg继承AppCompatImageView ,然后在res-values-attrs(没有attrs的自己创建个attrs的xml文件)添加自定义view可能用到的属性
然后就是下面代码,我尽量把注释写详细点
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import com.eluton.medclass.R;
import com.eluton.utils.LogUtil;
/**
* Created by admin on 2018/5/10.
*/
public class RoundImg extends AppCompatImageView {
private Paint paint;
private float radius = 2;//圆角半径
private boolean isCircle = true;
private boolean leftTop = false;//左上部分是否圆角
private boolean rightTop = false;//右上部分是否圆角
private boolean leftBottom = false;//左下部分是否圆角
private boolean rightBottom = false;//右下部分是否圆角
private int circlePad;//圆形图片的pad
public void setCirclePad(int circlePad) {
this.circlePad = circlePad;
}
public RoundImg(Context context) {
this(context, null);
}
public RoundImg(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundImg(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//获取在xml中定义的数据
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.RoundImg);
radius = array.getDimension(R.styleable.RoundImg_radius, 4);
isCircle = array.getBoolean(R.styleable.RoundImg_isCircle, true);
leftTop = array.getBoolean(R.styleable.RoundImg_leftTop, false);
rightTop = array.getBoolean(R.styleable.RoundImg_rightTop, false);
leftBottom = array.getBoolean(R.styleable.RoundImg_leftBottom, false);
rightBottom = array.getBoolean(R.styleable.RoundImg_rightBottom, false);
array.recycle();//拿到记得释放TypedArray
paint = new Paint();
}
/**
* 绘制圆角矩形图片
*
* @author caizhiming
*/
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable != null) {
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
// Bitmap bitmap = null;
// if (drawable instanceof GlideBitmapDrawable) {
// bitmap = ((GlideBitmapDrawable) drawable).getBitmap();
// } else {
// bitmap = ((BitmapDrawable) drawable).getBitmap();
// }
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas drawCanvas = new Canvas(bitmap);
float scale = 1.0f;
scale = Math.max(getWidth() * 1.0f / width, getHeight()
* 1.0f / height);
drawable.setBounds(0, 0, (int) (scale * width),
(int) (scale * height));
drawable.draw(drawCanvas);
Bitmap mMaskBitmap;
if (isCircle) {
mMaskBitmap = getCircle();
} else {
if (leftTop || rightTop || leftBottom || rightBottom) {
mMaskBitmap = getPathBitmap();
} else {
mMaskBitmap = getRect();
}
}
paint.setAntiAlias(true);
if (isCircle) {//给圆形图片外边画白描边
paint.setColor(getResources().getColor(R.color.white));
canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2, paint);
}
paint.reset();
paint.setFilterBitmap(false);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
//绘制形状
drawCanvas.drawBitmap(mMaskBitmap, 0, 0, paint);
//绘制图片
canvas.drawBitmap(bitmap, 0, 0, null);
paint.setXfermode(null);
} else {
super.onDraw(canvas);
}
}
@Override
public void invalidate() {
super.invalidate();
}
private Bitmap getCircle() {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
paint.setColor(Color.BLACK);
canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - 2, paint);
//getWidth() / 2 - 2 之所以-2,是故意把圆形图片画小一点,到时再画个背景,就成了带描边且描边边距为2px的圆形图片,就是说你描边要多少像素你就减少多少就是。其实我就是懒得把这属性也变成动态的
return bitmap;
}
public Bitmap getRect() {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
paint.setColor(Color.BLACK);
canvas.drawRoundRect(new RectF(0, 0, getWidth(), getHeight()), radius, radius, paint);
return bitmap;
}
private Bitmap getPathBitmap() {
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿
Path path = new Path();
// LogUtil.i("高度:" + getHeight());
path.moveTo(0, getHeight() / 2);
if (leftTop) {
// LogUtil.i("leftTop");
path.lineTo(0, radius);
RectF rectF = new RectF(0, 0, 2 * radius, 2 * radius);
path.arcTo(rectF, 180, 90);
} else {
path.lineTo(0, 0);
}
if (rightTop) {
path.lineTo(getWidth() - radius, 0);
RectF rectF2 = new RectF(getWidth() - 2 * radius, 0, getWidth(), 2 * radius);
path.arcTo(rectF2, 270, 90);
} else {
path.lineTo(getWidth(), 0);
}
if (rightBottom) {
path.lineTo(getWidth(), getHeight() - radius);
RectF rectF2 = new RectF(getWidth() - 2 * radius, getHeight() - 2 * radius, getWidth(), getHeight());
path.arcTo(rectF2, 0, 90);
} else {
path.lineTo(getWidth(), getHeight());
}
if (leftBottom) {
// LogUtil.i("leftBottom");
path.lineTo(radius, getHeight());
RectF rectF2 = new RectF(0, getHeight() - 2 * radius, 2 * radius, getHeight());
path.arcTo(rectF2, 90, 90);
} else {
path.lineTo(0, getHeight());
}
path.lineTo(0, getHeight() / 2);
// path.moveTo(0, getHeight());
// path.lineTo(0, getHeight() - radius);
// RectF rectF = new RectF(0, 0, 2 * radius, 2 * radius);
// path.arcTo(rectF, 180, 90);
// path.lineTo(getWidth() - radius, 0);
// RectF rectF2 = new RectF(getWidth() - 2 * radius, 0, getWidth(), 2 * radius);
// path.arcTo(rectF2, 270, 90);
// path.lineTo(getWidth(), getHeight());
// path.lineTo(0, getHeight());
canvas.drawPath(path, paint);
return bitmap;
}
}
直接在xml使用就行,在xml最外层加入 xmlns:app="http://schemas.android.com/apk/res-auto",这样才能调用自定义的view属性
app:isCircle="false"表示圆角图片,默认圆形图片,其他属性按自己需要添加就是。android:scaleType="fitCenter"是图片填充方式,根据自己需要修改就是