1 /**
2 * 实现圆形、圆角,椭圆等自定义图片View。3 * @author zq4 *5 */
6 public class ZQImageViewRoundOval extendsImageView {7
8 privatePaint mPaint;9
10 private intmWidth;11
12 private intmHeight;13
14 private int mRadius;//圆半径
15
16 private RectF mRect;//矩形凹行大小
17
18 private int mRoundRadius;//圆角大小
19
20 private BitmapShader mBitmapShader;//图形渲染
21
22 privateMatrix mMatrix;23
24 private int mType;//记录是圆形还是圆角矩形
25
26 public static final int TYPE_CIRCLE = 0;//圆形
27 public static final int TYPE_ROUND = 1;//圆角矩形
28 public static final int TYPE_OVAL = 2;//椭圆形
29 public static final int DEFAUT_ROUND_RADIUS = 10;//默认圆角大小
30
31 publicZQImageViewRoundOval(Context context) {32 this(context, null);33 //TODOAuto-generated constructor stub
34 }35
36 publicZQImageViewRoundOval(Context context, AttributeSet attrs) {37 this(context,attrs, 0);38 //TODOAuto-generated constructor stub
39 }40
41 public ZQImageViewRoundOval(Context context, AttributeSet attrs,intdefStyle){42 super(context,attrs, defStyle);43 initView();44 }45
46 private voidinitView() {47 mPaint = newPaint();48 mPaint.setAntiAlias(true);49 mMatrix = newMatrix();50 mRoundRadius =DEFAUT_ROUND_RADIUS;51 }52
53 @Override54 protected void onMeasure(intwidthMeasureSpec,intheightMeasureSpec) {55 //TODOAuto-generated method stub
56 super.onMeasure(widthMeasureSpec,heightMeasureSpec);57 //如果是绘制圆形,则强制宽高大小一致
58 if (mType ==TYPE_CIRCLE) {59 mWidth =Math.min(getMeasuredWidth(),getMeasuredHeight());60 mRadius = mWidth / 2;61 setMeasuredDimension(mWidth, mWidth);62 }63
64 }65
66 @Override67 protected voidonDraw(Canvas canvas) {68
69 if (null ==getDrawable()) {70 return;71 }72 setBitmapShader();73 if (mType ==TYPE_CIRCLE) {74 canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);75 } else if (mType ==TYPE_ROUND) {76 mPaint.setColor(Color.RED);77 canvas.drawRoundRect(mRect, mRoundRadius, mRoundRadius, mPaint);78 }else if(mType ==TYPE_OVAL){79 canvas.drawOval(mRect, mPaint);80 }81 }82
83 @Override84 protected void onSizeChanged(int w,int h, int oldw,intoldh) {85 //TODOAuto-generated method stub
86 super.onSizeChanged(w,h, oldw, oldh);87 mRect = new RectF(0,0, getWidth(), getHeight());88 }89
90 /**
91 * 设置BitmapShader92 */
93 private voidsetBitmapShader() {94 Drawable drawable =getDrawable();95 if (null ==drawable) {96 return;97 }98 Bitmap bitmap =drawableToBitmap(drawable);99 //将bitmap作为着色器来创建一个BitmapShader
100 mBitmapShader =newBitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);101 float scale =1.0f;102 if (mType ==TYPE_CIRCLE) {103 //拿到bitmap宽或高的小值
104 int bSize =Math.min(bitmap.getWidth(), bitmap.getHeight());105 scale = mWidth * 1.0f /bSize;106
107 } else if (mType == TYPE_ROUND ||mType ==TYPE_OVAL) {108 //如果图片的宽或者高与view的宽高不匹配,计算出需要缩放的比例;缩放后的图片的宽高,一定要大于我们view的宽高;所以我们这里取大值;
109 scale = Math.max(getWidth() * 1.0f/ bitmap.getWidth(), getHeight() * 1.0f /bitmap.getHeight());110 }111 //shader的变换矩阵,我们这里主要用于放大或者缩小
112 mMatrix.setScale(scale,scale);113 //设置变换矩阵
114 mBitmapShader.setLocalMatrix(mMatrix);115 mPaint.setShader(mBitmapShader);116
117 }118
119 /**
120 * drawable转bitmap121 *122 * @paramdrawable123 *@return
124 */
125 privateBitmap drawableToBitmap(Drawable drawable) {126 if(drawableinstanceof BitmapDrawable) {127 BitmapDrawable bitmapDrawable =(BitmapDrawable) drawable;128 returnbitmapDrawable.getBitmap();129 }130 int w =drawable.getIntrinsicWidth();131 int h =drawable.getIntrinsicHeight();132 Bitmap bitmap =Bitmap.createBitmap(w,h, Config.ARGB_8888);133 Canvas canvas =newCanvas(bitmap);134 drawable.setBounds(0, 0, w, h);135 drawable.draw(canvas);136 returnbitmap;137 }138 /**
139 * 单位dp转单位px140 */
141 public int dpTodx(intdp){142
143 return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,144 dp,getResources().getDisplayMetrics());145 }146
147 public intgetType(){148 returnmType;149 }150 /**
151 * 设置图片类型:圆形、圆角矩形、椭圆形152 *@parammType153 */
154 public void setType(intmType) {155 if(this.mType !=mType){156 this.mType =mType;157 invalidate();158 }159
160 }161 public intgetRoundRadius() {162 returnmRoundRadius;163 }164 /**
165 * 设置圆角大小166 * @parammRoundRadius167 */
168 public void setRoundRadius(intmRoundRadius) {169 if(this.mRoundRadius !=mRoundRadius){170 this.mRoundRadius =mRoundRadius;171 invalidate();172 }173
174 }175 }