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 static final int DEFAULT_FILL_COLOR =Color.TRANSPARENT;private static final boolean DEFAULT_BORDER_OVERLAY = false;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 final Paint mFillPaint = newPaint();private int mBorderColor =DEFAULT_BORDER_COLOR;private int mBorderWidth =DEFAULT_BORDER_WIDTH;private int mFillColor =DEFAULT_FILL_COLOR;privateBitmap mBitmap;privateBitmapShader mBitmapShader;private intmBitmapWidth;private intmBitmapHeight;private floatmDrawableRadius;private floatmBorderRadius;privateColorFilter mColorFilter;private booleanmReady;private booleanmSetupPending;private booleanmBorderOverlay;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_civ_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor=a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay=a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
mFillColor=a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_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 (mBitmap == null) {return;
}if (mFillColor !=Color.TRANSPARENT) {
canvas.drawCircle(getWidth()/ 2.0f, getHeight() / 2.0f, mDrawableRadius, mFillPaint);
}
canvas.drawCircle(getWidth()/ 2.0f, getHeight() / 2.0f, mDrawableRadius, mBitmapPaint);if (mBorderWidth != 0) {
canvas.drawCircle(getWidth()/ 2.0f, getHeight() / 2.0f, 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(@ColorInt int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}*/
/*public void setBorderColorResource(@ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}*/
public intgetFillColor() {returnmFillColor;
}/*public void setFillColor(@ColorInt int fillColor) {
if (fillColor == mFillColor) {
return;
}
mFillColor = fillColor;
mFillPaint.setColor(fillColor);
invalidate();
}*/
/*public void setFillColorResource(@ColorRes int fillColorRes) {
setFillColor(getContext().getResources().getColor(fillColorRes));
}*/
public intgetBorderWidth() {returnmBorderWidth;
}public void setBorderWidth(intborderWidth) {if (borderWidth ==mBorderWidth) {return;
}
mBorderWidth=borderWidth;
setup();
}public booleanisBorderOverlay() {returnmBorderOverlay;
}public void setBorderOverlay(booleanborderOverlay) {if (borderOverlay ==mBorderOverlay) {return;
}
mBorderOverlay=borderOverlay;
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(@DrawableRes intresId) {super.setImageResource(resId);
mBitmap=getBitmapFromDrawable(getDrawable());
setup();
}
@Overridepublic voidsetImageURI(Uri uri) {super.setImageURI(uri);
mBitmap= uri != null ? getBitmapFromDrawable(getDrawable()) : null;
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(Exception e) {
e.printStackTrace();return null;
}
}private voidsetup() {if (!mReady) {
mSetupPending= true;return;
}if (getWidth() == 0 && getHeight() == 0) {return;
}if (mBitmap == null) {
invalidate();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);
mFillPaint.setStyle(Paint.Style.FILL);
mFillPaint.setAntiAlias(true);
mFillPaint.setColor(mFillColor);
mBitmapHeight=mBitmap.getHeight();
mBitmapWidth=mBitmap.getWidth();
mBorderRect.set(0, 0, getWidth(), getHeight());
mBorderRadius= Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
mDrawableRect.set(mBorderRect);if (!mBorderOverlay) {
mDrawableRect.inset(mBorderWidth, mBorderWidth);
}
mDrawableRadius= Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
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) + mDrawableRect.left, (int) (dy + 0.5f) +mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}