import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ImageView;
import
com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
import com.isgo.isgogallery.R;
public class RectangleView extends ImageView{
public static int SHAPE_REC =
1;
public static int SHAPE_CIRCLE =
2;
public static int SHAPE_OVAL =
3;
private float mBorderSize =
0;
private int mBorderColor = Color.WHITE;
private int mShape = SHAPE_REC;
private float mRoundRadius =
0;
private Paint mBorderPaint =
new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF mViewRect =
new RectF();
private RectF mBorderRect =
new RectF();
private final Matrix mShaderMatrix =
new Matrix();
private Paint mBitmapPaint =
new Paint();
private BitmapShader mBitmapShader;
private Bitmap mBitmap;
public RectangleView(Context context, AttributeSet attrs) {
this(context, attrs,
0);
}
public RectangleView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(attrs);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderSize);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setAntiAlias(
true);
mBitmapPaint.setAntiAlias(
true);
super.setScaleType(ScaleType.CENTER_CROP);
}
@Override
public void setImageResource(
int resId) {
super.setImageResource(resId);
mBitmap = getBitmapFromDrawable(getDrawable());
setupBitmapShader();
}
@Override
public void setBackgroundResource(
int resid) {
super.setBackgroundResource(resid);
mBitmap = getBitmapFromDrawable( getResources().getDrawable(resid));
setupBitmapShader();
}
@Override
public void setBackgroundDrawable(Drawable background) {
super.setBackgroundDrawable(background);
mBitmap = getBitmapFromDrawable(background);
setupBitmapShader();
}
@Override
public void setBackground(Drawable background) {
super.setBackground(background);
mBitmap = getBitmapFromDrawable(background);
setupBitmapShader();
}
private Bitmap
getBitmapFromDrawable(Drawable drawable) {
if(drawable !=
null){
if(drawable
instanceof GlideBitmapDrawable){
return ((GlideBitmapDrawable)drawable).getBitmap();
}
else if(drawable
instanceof BitmapDrawable){
return ((BitmapDrawable)drawable).getBitmap();
}
}
return null;
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap = getBitmapFromDrawable(drawable);
setupBitmapShader();
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != ScaleType.CENTER_CROP) {
throw new IllegalArgumentException(String.format(
"ScaleType %s not supported.", scaleType));
}
}
private void init(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.RectangleView);
mShape = a.getInt(R.styleable.RectangleView_shape, mShape);
mRoundRadius = a.getDimension(R.styleable.RectangleView_round_radius, mRoundRadius);
mBorderSize = a.getDimension(R.styleable.RectangleView_border_size, mBorderSize);
mBorderColor = a.getColor(R.styleable.RectangleView_border_color1, mBorderColor);
a.recycle();
}
/**
* 对于普通的view,在执行到onDraw()时,背景图已绘制完成
* <p/>
* 对于ViewGroup,当它没有背景时直接调用的是dispatchDraw()方法, 而绕过了draw()方法,
* 当它有背景的时候就调用draw()方法,而draw()方法里包含了dispatchDraw()方法的调用,
*/
@Override
public void onDraw(Canvas canvas) {
if (getDrawable() !=
null) {
if (mShape == SHAPE_CIRCLE) {
canvas.drawCircle(getWidth() /
2, getHeight() /
2,
Math.min(getWidth(), getHeight()) /
2, mBitmapPaint);
}
else if (mShape == SHAPE_OVAL) {
canvas.drawOval(mViewRect, mBitmapPaint);
}
else {
canvas.drawRoundRect(mViewRect, mRoundRadius, mRoundRadius, mBitmapPaint);
}
}
if (mBorderSize >
0) {
if (mShape == SHAPE_CIRCLE) {
canvas.drawCircle(mViewRect.right /
2, mViewRect.bottom /
2,
Math.min(mViewRect.right, mViewRect.bottom) /
2 - mBorderSize /
2, mBorderPaint);
}
else if (mShape == SHAPE_OVAL) {
canvas.drawOval(mBorderRect, mBorderPaint);
}
else {
canvas.drawRoundRect(mBorderRect, mRoundRadius, mRoundRadius, mBorderPaint);
}
}
}
@Override
protected void onSizeChanged(
int w,
int h,
int oldw,
int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
initRect();
setupBitmapShader();
}
@Override
protected void onLayout(
boolean changed,
int left,
int top,
int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
private void setupBitmapShader() {
if (mBitmapPaint ==
null) {
return;
}
if (mBitmap ==
null) {
invalidate();
return;
}
mBitmapShader =
new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setShader(mBitmapShader);
mShaderMatrix.set(
null);
float scale = Math.max(getWidth() *
1f / mBitmap.getWidth(), getHeight() *
1f / mBitmap.getHeight());
float dx = (getWidth() - mBitmap.getWidth() * scale) /
2;
float dy = (getHeight() - mBitmap.getHeight() * scale) /
2;
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate(dx, dy);
mBitmapShader.setLocalMatrix(mShaderMatrix);
invalidate();
}
private void initRect() {
mViewRect.top =
0;
mViewRect.left =
0;
mViewRect.right = getWidth();
mViewRect.bottom = getHeight();
mBorderRect.top = mBorderSize /
2;
mBorderRect.left = mBorderSize /
2;
mBorderRect.right = getWidth() - mBorderSize /
2;
mBorderRect.bottom = getHeight() - mBorderSize /
2;
}
public int getShape() {
return mShape;
}
public void setShape(
int shape) {
mShape = shape;
}
public float getBorderSize() {
return mBorderSize;
}
public void setBorderSize(
int mBorderSize) {
this.mBorderSize = mBorderSize;
mBorderPaint.setStrokeWidth(mBorderSize);
initRect();
invalidate();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(
int mBorderColor) {
this.mBorderColor = mBorderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public float getRoundRadius() {
return mRoundRadius;
}
public void setRoundRadius(
float mRoundRadius) {
this.mRoundRadius = mRoundRadius;
invalidate();
}
}