ImageView显示的视图是方形的,想实现类似ImageView的圆形视图控件,于是刚开始的思路是继承Imageview,重写onMeasure和onDraw方法去实现,然而最终的结果是方形视图和圆形视图的叠加效果(下面一层是方形视图,上面一层是圆形视图)。后来改变思路,直接继承View去实现圆形视图效果,然后就成功了。后来想了下,继承ImageView实现不了的原因应该是由于虽然重写了onDraw方法去实现圆形视图,但是它是在方形视图的基础上显示的圆形视图,所以就出现了叠加的效果(不晓得是不是这个原因)。
继承View实现圆形视图代码如下:
1 public class CircleImageView extends View { 2 private Paint mPaint; 3 private Matrix matrix; 4 int circleWidth; 5 Bitmap bitmap; 6 7 public CircleImageView(Context context) { 8 super(context); 9 init(); 10 } 11 public CircleImageView(Context context,AttributeSet attrs){ 12 this(context,attrs,0); 13 } 14 public CircleImageView(Context context,AttributeSet attrs,int defStyleAttr){ 15 super(context, attrs, defStyleAttr); 16 init(); 17 } 18 19 private void init() { 20 mPaint = new Paint(); 21 //去锯齿效果 22 mPaint.setAntiAlias(true); 23 mPaint.setColor(Color.BLACK); 24 mPaint.setStyle(Paint.Style.FILL); 25 matrix = new Matrix(); 26 } 27 28 @Override 29 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 30 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 31 circleWidth = Math.min(getMeasuredWidth(), getMeasuredHeight()); 32 int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); 33 int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); 34 int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); 35 int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); 36 if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) { 37 setMeasuredDimension(circleWidth, circleWidth); 38 } else if (widthSpecMode == MeasureSpec.AT_MOST) { 39 setMeasuredDimension(circleWidth, heightSpecSize); 40 } else if (heightSpecMode == MeasureSpec.AT_MOST) { 41 setMeasuredDimension(widthSpecSize, circleWidth); 42 } 43 } 44 45 @Override 46 protected void onDraw(Canvas canvas) { 47 super.onDraw(canvas); 48 int paddingLeft = getPaddingLeft(); 49 int paddingRight = getPaddingRight(); 50 int paddingTop = getPaddingTop(); 51 int paddingBottom = getPaddingBottom(); 52 int width = getWidth() - paddingLeft - paddingRight; 53 int height = getHeight() - paddingTop - paddingBottom; 54 int radius = Math.min(width, height) / 2; 55 setBitmapShader(); 56 canvas.drawCircle(paddingLeft + width / 2, paddingTop + height / 2, radius, mPaint); 57 } 58 59 public void setImageBitmap(Bitmap srcbitmap) { 60 bitmap = srcbitmap; 61 } 62 63 private void setBitmapShader() { 64 double scale = 1; 65 float dx = 0, dy = 0; 66 BitmapShader bitmapShader = new BitmapShader(bitmap, 67 Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 68 //图片宽高 69 int bitmapWidth = bitmap.getWidth(); 70 int bitmapHeight = bitmap.getHeight(); 71 //视图宽高 72 int viewWidth = getWidth(); 73 int viewHeight = getHeight(); 74 //计算缩放比例 75 int bSize = Math.min(bitmapWidth, bitmapHeight); 76 scale = circleWidth * 1.0 / bSize; 77 if (bitmapWidth * viewHeight > bitmapHeight * viewWidth) { 78 dx = (float) ((viewWidth - bitmapWidth * scale) * 0.5f); 79 } else { 80 dy = (float) ((viewHeight - bitmapHeight * scale) * 0.5f); 81 } 82 matrix.setScale((float) scale, (float) scale); 83 matrix.postTranslate(dx, dy); 84 bitmapShader.setLocalMatrix(matrix); 85 mPaint.setShader(bitmapShader); 86 } 87 88 }