public class CircleImageView extends ImageView {
privatestatic final ScaleType SCALE_TYPE = ScaleType.CENTER_CROP;
privatestatic final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
privatestatic final int COLORDRAWABLE_DIMENSION = 1;
privatestatic final int DEFAULT_BORDER_WIDTH = 0;
privatestatic final int DEFAULT_BORDER_COLOR = Color.BLACK;
private finalRectF mDrawableRect = new RectF();
private finalRectF mBorderRect = new RectF();
private finalMatrix mShaderMatrix = new Matrix();
private finalPaint mBitmapPaint = new Paint();
private finalPaint mBorderPaint = new Paint();
private intmBorderColor = DEFAULT_BORDER_COLOR;
private intmBorderWidth = DEFAULT_BORDER_WIDTH;
privateBitmap mBitmap;
privateBitmapShader mBitmapShader;
private intmBitmapWidth;
private intmBitmapHeight;
private floatmDrawableRadius;
private floatmBorderRadius;
privateboolean mReady;
privateboolean mSetupPending;
publicCircleImageView(Context context) {
super(context);
}
publicCircleImageView(Context context, AttributeSet attrs) {
this(context,attrs, 0);
}
publicCircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context,attrs, defStyle);
super.setScaleType(SCALE_TYPE);
TypedArraya = 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();
mReady =true;
if(mSetupPending) {
setup();
mSetupPending= false;
}
}
@Override
publicScaleType getScaleType() {
returnSCALE_TYPE;
}
@Override
public voidsetScaleType(ScaleType scaleType) {
if(scaleType != SCALE_TYPE) {
thrownew IllegalArgumentException(String.format(
"ScaleType%s not supported.", scaleType));
}
}
@Override
protectedvoid onDraw(Canvas canvas) {
if(getDrawable() == null) {
return;
}
canvas.drawCircle(getWidth()/ 2, getHeight() / 2, mDrawableRadius,
mBitmapPaint);
canvas.drawCircle(getWidth()/ 2, getHeight() / 2, mBorderRadius,
mBorderPaint);
}
@Override
protectedvoid onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w,h, oldw, oldh);
setup();
}
public intgetBorderColor() {
returnmBorderColor;
}
public voidsetBorderColor(int borderColor) {
if(borderColor == mBorderColor) {
return;
}
mBorderColor= borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
public intgetBorderWidth() {
returnmBorderWidth;
}
public voidsetBorderWidth(int borderWidth) {
if(borderWidth == mBorderWidth) {
return;
}
mBorderWidth= borderWidth;
setup();
}
@Override
public voidsetImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
mBitmap =bm;
setup();
}
@Override
public voidsetImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
mBitmap =getBitmapFromDrawable(drawable);
setup();
}
@Override
public voidsetImageResource(int resId) {
super.setImageResource(resId);
mBitmap =getBitmapFromDrawable(getDrawable());
setup();
}
privateBitmap getBitmapFromDrawable(Drawable drawable) {
if(drawable == null) {
returnnull;
}
if(drawable instanceof BitmapDrawable) {
return((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmapbitmap;
if(drawable instanceof ColorDrawable) {
bitmap= Bitmap.createBitmap(COLORDRAWABLE_DIMENSION,
COLORDRAWABLE_DIMENSION,BITMAP_CONFIG);
}else {
bitmap= Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),BITMAP_CONFIG);
}
Canvascanvas = new Canvas(bitmap);
drawable.setBounds(0,0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
returnbitmap;
} catch(OutOfMemoryError e) {
returnnull;
}
}
private voidsetup() {
if(!mReady) {
mSetupPending= true;
return;
}
if(mBitmap == null) {
return;
}
mBitmapShader= new BitmapShader(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);
}
}