首先是自定义类CircleImageView
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.ColorDrawable ;
import android.graphics.drawable.Drawable ;
import android.util.AttributeSet ;
import android.widget.ImageView ;
public class CircleImageView extends ImageView {
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 = 1 ;
private static final int DEFAULT_BORDER_WIDTH = 0 ;
private static final int DEFAULT_BORDER_COLOR = Color. BLACK ;
private final RectF mDrawableRect = new RectF() ;
private final RectF mBorderRect = new RectF() ;
private final Matrix mShaderMatrix = new Matrix() ;
private final Paint mBitmapPaint = new Paint() ;
private final Paint mBorderPaint = new Paint() ;
private int mBorderColor = DEFAULT_BORDER_COLOR ;
private int mBorderWidth = DEFAULT_BORDER_WIDTH ;
private Bitmap mBitmap ;
private BitmapShader mBitmapShader ;
private int mBitmapWidth ;
private int mBitmapHeight ;
private float mDrawableRadius ;
private float mBorderRadius ;
private boolean mReady ;
private boolean mSetupPending ;
public CircleImageView(Context context) {
super(context) ;
}
public CircleImageView(Context context , AttributeSet attrs) {
this(context , attrs , 0) ;
}
public CircleImageView(Context context , AttributeSet attrs , int defStyle) {
super(context , attrs , defStyle) ;
super.setScaleType( SCALE_TYPE) ;
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() ;
mReady = true;
if ( mSetupPending) {
setup() ;
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE ;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String. format( "ScaleType %s not supported." , scaleType)) ;
}
}
@Override
protected void onDraw(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) ;
}
}
@Override
protected void onSizeChanged( int w , int h , int oldw , int oldh) {
super.onSizeChanged(w , h , oldw , oldh) ;
setup() ;
}
public int getBorderColor() {
return mBorderColor ;
}
public void setBorderColor( int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor ;
mBorderPaint.setColor( mBorderColor) ;
invalidate() ;
}
public int getBorderWidth() {
return mBorderWidth ;
}
public void setBorderWidth( int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth ;
setup() ;
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm) ;
mBitmap = bm ;
setup() ;
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable) ;
mBitmap = getBitmapFromDrawable(drawable) ;
setup() ;
}
@Override
public void setImageResource( int resId) {
super.setImageResource(resId) ;
mBitmap = getBitmapFromDrawable(getDrawable()) ;
setup() ;
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
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.ColorDrawable ;
import android.graphics.drawable.Drawable ;
import android.util.AttributeSet ;
import android.widget.ImageView ;
public class CircleImageView extends ImageView {
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 = 1 ;
private static final int DEFAULT_BORDER_WIDTH = 0 ;
private static final int DEFAULT_BORDER_COLOR = Color. BLACK ;
private final RectF mDrawableRect = new RectF() ;
private final RectF mBorderRect = new RectF() ;
private final Matrix mShaderMatrix = new Matrix() ;
private final Paint mBitmapPaint = new Paint() ;
private final Paint mBorderPaint = new Paint() ;
private int mBorderColor = DEFAULT_BORDER_COLOR ;
private int mBorderWidth = DEFAULT_BORDER_WIDTH ;
private Bitmap mBitmap ;
private BitmapShader mBitmapShader ;
private int mBitmapWidth ;
private int mBitmapHeight ;
private float mDrawableRadius ;
private float mBorderRadius ;
private boolean mReady ;
private boolean mSetupPending ;
public CircleImageView(Context context) {
super(context) ;
}
public CircleImageView(Context context , AttributeSet attrs) {
this(context , attrs , 0) ;
}
public CircleImageView(Context context , AttributeSet attrs , int defStyle) {
super(context , attrs , defStyle) ;
super.setScaleType( SCALE_TYPE) ;
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() ;
mReady = true;
if ( mSetupPending) {
setup() ;
mSetupPending = false;
}
}
@Override
public ScaleType getScaleType() {
return SCALE_TYPE ;
}
@Override
public void setScaleType(ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String. format( "ScaleType %s not supported." , scaleType)) ;
}
}
@Override
protected void onDraw(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) ;
}
}
@Override
protected void onSizeChanged( int w , int h , int oldw , int oldh) {
super.onSizeChanged(w , h , oldw , oldh) ;
setup() ;
}
public int getBorderColor() {
return mBorderColor ;
}
public void setBorderColor( int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor ;
mBorderPaint.setColor( mBorderColor) ;
invalidate() ;
}
public int getBorderWidth() {
return mBorderWidth ;
}
public void setBorderWidth( int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth ;
setup() ;
}
@Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm) ;
mBitmap = bm ;
setup() ;
}
@Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable) ;
mBitmap = getBitmapFromDrawable(drawable) ;
setup() ;
}
@Override
public void setImageResource( int resId) {
super.setImageResource(resId) ;
mBitmap = getBitmapFromDrawable(getDrawable()) ;
setup() ;
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {