📅  最后修改于: 2023-12-03 15:23:05.834000             🧑  作者: Mango
在Android开发中,ImageView是非常常用的控件。但是在某些情况下,我们可能需要将ImageView的四个角变成圆角。本文将介绍三种实现圆角ImageView的方法,分别是:
1.使用BitmapShader+Canvas绘制
public class RoundImageView extends ImageView {
private Paint mPaint;
private Path mPath;
private int mRadius = 10;//默认圆角大小
public RoundImageView(Context context) {
this(context, null);
}
public RoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPath = new Path();
//获取属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
mRadius = ta.getDimensionPixelSize(R.styleable.RoundImageView_radius, mRadius);
ta.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
return;
}
//先把图片画上
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
mPaint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
canvas.save();
//画圆角
getRoundPath(getWidth(), getHeight(), mPath, mRadius);
canvas.drawPath(mPath, mPaint);
canvas.restore();
}
private void getRoundPath(int width, int height, Path path, int radius) {
path.reset();
path.addRoundRect(new RectF(0, 0, width, height), radius, radius, Path.Direction.CW);
}
public void setRadius(int radius) {
mRadius = radius;
invalidate();
}
}
这种方法的原理是通过将ImageView的drawable转成bitmap,并使用BitmapShader来绘制圆角。这种方法比较简单,但是不支持xml属性设置,也不支持边框等其他特性。
2.使用ClipPath裁剪
public class RoundImageView extends ImageView {
private Path mPath;
private int mRadius = 10;//默认圆角大小
public RoundImageView(Context context) {
this(context, null);
}
public RoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPath = new Path();
//获取属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
mRadius = ta.getDimensionPixelSize(R.styleable.RoundImageView_radius, mRadius);
ta.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onDraw(canvas);
return;
}
canvas.save();
//画圆角
getRoundPath(getWidth(), getHeight(), mPath, mRadius);
canvas.clipPath(mPath);
//先把图片画上
super.onDraw(canvas);
canvas.restore();
}
private void getRoundPath(int width, int height, Path path, int radius) {
path.reset();
path.addRoundRect(new RectF(0, 0, width, height), radius, radius, Path.Direction.CW);
}
public void setRadius(int radius) {
mRadius = radius;
invalidate();
}
}
这种方法的原理是通过ClipPath裁剪出圆角矩形区域,从而达到圆角效果。这种方法可以支持xml属性设置,但是对于一些特殊情况,如边框,阴影等效果不支持。
3.使用RoundRectShape和ShapeDrawable
public class RoundImageView extends androidx.appcompat.widget.AppCompatImageView {
private ShapeDrawable mShapeDrawable;
private int mRadius = 10;//默认圆角大小
public RoundImageView(Context context) {
this(context, null);
}
public RoundImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//获取属性
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundImageView);
mRadius = ta.getDimensionPixelSize(R.styleable.RoundImageView_radius, mRadius);
ta.recycle();
mShapeDrawable = new ShapeDrawable(new RoundRectShape(new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}, null, null));
setBackground(mShapeDrawable);
}
public void setRadius(int radius) {
mRadius = radius;
mShapeDrawable.setShape(new RoundRectShape(new float[]{mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius, mRadius}, null, null));
}
}
这种方法的原理是通过ShapeDrawable和RoundRectShape设置圆角矩形。这种方法可以支持xml属性设置,也可以支持边框,阴影等其他特性。
总结:
三种方法都能完成圆角ImageView的效果,选择哪种方法,就要看具体的需求了。
1.如果要求简单,只是简单的圆角效果,可以选择第一种方法。
2.如果要求支持xml属性设置,可以选择第二种方法。
3.如果要求支持其他特性,如边框,阴影等效果,可以选择第三种方法。
如果有特殊需求,可以自己去扩展。