packagede.hdodenhof.circleimageview;importandroid.content.Context;importandroid.content.res.TypedArray;importandroid.graphics.Bitmap;importandroid.graphics.BitmapShader;importandroid.graphics.Canvas;importandroid.graphics.Color;importandroid.graphics.ColorFilter;importandroid.graphics.Matrix;importandroid.graphics.Paint;importandroid.graphics.RectF;importandroid.graphics.Shader;importandroid.graphics.drawable.BitmapDrawable;importandroid.graphics.drawable.ColorDrawable;importandroid.graphics.drawable.Drawable;importandroid.net.Uri;importandroid.util.AttributeSet;importandroid.widget.ImageView;public class CircleImageView extendsImageView {private static final ScaleType SCALE_TYPE =ScaleType.CENTER_CROP;private static final Bitmap.Config BITMAP_CONFIG =Bitmap.Config.ARGB_8888;private static final int COLORDRAWABLE_DIMENSION = 2;private static final int DEFAULT_BORDER_WIDTH = 0;private static final int DEFAULT_BORDER_COLOR =Color.BLACK;private final RectF mDrawableRect = newRectF();private final RectF mBorderRect = newRectF();private final Matrix mShaderMatrix = newMatrix();private final Paint mBitmapPaint = newPaint();private final Paint mBorderPaint = newPaint();private int mBorderColor =DEFAULT_BORDER_COLOR;private int mBorderWidth =DEFAULT_BORDER_WIDTH;privateBitmap mBitmap;privateBitmapShader mBitmapShader;private intmBitmapWidth;private intmBitmapHeight;private floatmDrawableRadius;private floatmBorderRadius;privateColorFilter mColorFilter;private booleanmReady;private booleanmSetupPending;publicCircleImageView(Context context) {super(context);

init();

}publicCircleImageView(Context context, AttributeSet attrs) {this(context, attrs, 0);

}public CircleImageView(Context context, AttributeSet attrs, intdefStyle) {super(context, attrs, defStyle);

TypedArray a= context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);

mBorderWidth=a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);

mBorderColor=a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);

a.recycle();

init();

}private voidinit() {super.setScaleType(SCALE_TYPE);

mReady= true;if(mSetupPending) {

setup();

mSetupPending= false;

}

}

@OverridepublicScaleType getScaleType() {returnSCALE_TYPE;

}

@Overridepublic voidsetScaleType(ScaleType scaleType) {if (scaleType !=SCALE_TYPE) {throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));

}

}

@Overridepublic void setAdjustViewBounds(booleanadjustViewBounds) {if(adjustViewBounds) {throw new IllegalArgumentException("adjustViewBounds not supported.");

}

}

@Overrideprotected voidonDraw(Canvas canvas) {if (getDrawable() == null) {return;

}

canvas.drawCircle(getWidth()/ 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);if (mBorderWidth != 0) {

canvas.drawCircle(getWidth()/ 2, getHeight() / 2, mBorderRadius, mBorderPaint);

}

}

@Overrideprotected void onSizeChanged(int w, int h, int oldw, intoldh) {super.onSizeChanged(w, h, oldw, oldh);

setup();

}public intgetBorderColor() {returnmBorderColor;

}public void setBorderColor(intborderColor) {if (borderColor ==mBorderColor) {return;

}

mBorderColor=borderColor;

mBorderPaint.setColor(mBorderColor);

invalidate();

}public intgetBorderWidth() {returnmBorderWidth;

}public void setBorderWidth(intborderWidth) {if (borderWidth ==mBorderWidth) {return;

}

mBorderWidth=borderWidth;

setup();

}

@Overridepublic voidsetImageBitmap(Bitmap bm) {super.setImageBitmap(bm);

mBitmap=bm;

setup();

}

@Overridepublic voidsetImageDrawable(Drawable drawable) {super.setImageDrawable(drawable);

mBitmap=getBitmapFromDrawable(drawable);

setup();

}

@Overridepublic void setImageResource(intresId) {super.setImageResource(resId);

mBitmap=getBitmapFromDrawable(getDrawable());

setup();

}

@Overridepublic voidsetImageURI(Uri uri) {super.setImageURI(uri);

mBitmap=getBitmapFromDrawable(getDrawable());

setup();

}

@Overridepublic voidsetColorFilter(ColorFilter cf) {if (cf ==mColorFilter) {return;

}

mColorFilter=cf;

mBitmapPaint.setColorFilter(mColorFilter);

invalidate();

}privateBitmap getBitmapFromDrawable(Drawable drawable) {if (drawable == null) {return null;

}if (drawable instanceofBitmapDrawable) {return((BitmapDrawable) drawable).getBitmap();

}try{

Bitmap bitmap;if (drawable instanceofColorDrawable) {

bitmap=Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);

}else{

bitmap=Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);

}

Canvas canvas= newCanvas(bitmap);

drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());

drawable.draw(canvas);returnbitmap;

}catch(OutOfMemoryError e) {return null;

}

}private voidsetup() {if (!mReady) {

mSetupPending= true;return;

}if (mBitmap == null) {return;

}

mBitmapShader= newBitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);

mBitmapPaint.setAntiAlias(true);

mBitmapPaint.setShader(mBitmapShader);

mBorderPaint.setStyle(Paint.Style.STROKE);

mBorderPaint.setAntiAlias(true);

mBorderPaint.setColor(mBorderColor);

mBorderPaint.setStrokeWidth(mBorderWidth);

mBitmapHeight=mBitmap.getHeight();

mBitmapWidth=mBitmap.getWidth();

mBorderRect.set(0, 0, getWidth(), getHeight());

mBorderRadius= Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);

mDrawableRect.set(mBorderWidth, mBorderWidth, mBorderRect.width()- mBorderWidth, mBorderRect.height() -mBorderWidth);

mDrawableRadius= Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);

updateShaderMatrix();

invalidate();

}private voidupdateShaderMatrix() {floatscale;float dx = 0;float dy = 0;

mShaderMatrix.set(null);if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() *mBitmapHeight) {

scale= mDrawableRect.height() / (float) mBitmapHeight;

dx= (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;

}else{

scale= mDrawableRect.width() / (float) mBitmapWidth;

dy= (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;

}

mShaderMatrix.setScale(scale, scale);

mShaderMatrix.postTranslate((int) (dx + 0.5f) + mBorderWidth, (int) (dy + 0.5f) +mBorderWidth);

mBitmapShader.setLocalMatrix(mShaderMatrix);

}

}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐