Android中的ImageView只能显示矩形的图片,为了用户体验更多,Android实现圆角矩形,圆形或者椭圆等图形,一般通过自定义ImageView来实现,首先获取到图片的Bitmap,然后通过Paint和onDraw()进行圆形图片显示。
效果图:
代码:
1 /** 2 * 实现圆形、圆角,椭圆等自定义图片View。 3 * @author zq 4 * 5 */ 6 public class ZQImageViewRoundOval extends ImageView { 7 8 private Paint mPaint; 9 10 private int mWidth; 11 12 private int mHeight; 13 14 private int mRadius;//圆半径 15 16 private RectF mRect;//矩形凹行大小 17 18 private int mRoundRadius;//圆角大小 19 20 private BitmapShader mBitmapShader;//图形渲染 21 22 private Matrix 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 public ZQImageViewRoundOval(Context context) { 32 this(context, null); 33 // TODOAuto-generated constructor stub 34 } 35 36 public ZQImageViewRoundOval(Context context, AttributeSet attrs) { 37 this(context,attrs, 0); 38 // TODOAuto-generated constructor stub 39 } 40 41 public ZQImageViewRoundOval(Context context, AttributeSet attrs,int defStyle){ 42 super(context,attrs, defStyle); 43 initView(); 44 } 45 46 private void initView() { 47 mPaint = new Paint(); 48 mPaint.setAntiAlias(true); 49 mMatrix = new Matrix(); 50 mRoundRadius = DEFAUT_ROUND_RADIUS; 51 } 52 53 @Override 54 protected void onMeasure(int widthMeasureSpec,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 @Override 67 protected void onDraw(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 @Override 84 protected void onSizeChanged(int w,int h, int oldw,int oldh) { 85 // TODOAuto-generated method stub 86 super.onSizeChanged(w,h, oldw, oldh); 87 mRect = new RectF(0,0, getWidth(), getHeight()); 88 } 89 90 /** 91 * 设置BitmapShader 92 */ 93 private void setBitmapShader() { 94 Drawable drawable = getDrawable(); 95 if (null ==drawable) { 96 return; 97 } 98 Bitmap bitmap = drawableToBitmap(drawable); 99 // 将bitmap作为着色器来创建一个BitmapShader100 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 * @return124 */125 private Bitmap 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 return bitmap;137 }138 /**139 * 单位dp转单位px140 */141 public int dpTodx(int dp){142 143 return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 144 dp,getResources().getDisplayMetrics()); 145 }146 147 public int getType(){148 return mType;149 }150 /**151 * 设置图片类型:圆形、圆角矩形、椭圆形152 * @param mType153 */154 public void setType(int mType) {155 if(this.mType !=mType){156 this.mType = mType;157 invalidate();158 }159 160 }161 public int getRoundRadius() {162 return mRoundRadius;163 }164 /**165 * 设置圆角大小166 * @parammRoundRadius167 */168 public void setRoundRadius(int mRoundRadius) {169 if(this.mRoundRadius !=mRoundRadius){170 this.mRoundRadius =mRoundRadius;171 invalidate();172 }173 174 }175 }
1 MainActivity类 2 /**** 3 * 4 * 自定义ImageView实现圆形图片,圆角矩形图片 椭圆图片 5 * 6 * @authorzq 7 * 8 */ 9 public class MainActivity extends Activity {10 11 12 private ZQImageViewRoundOvaliv_circle;//圆形图片13 private ZQImageViewRoundOvaliv_roundRect;//圆角矩形图片14 private ZQImageViewRoundOvaliv_oval;//椭圆图片15 @Override16 protected void onCreate(Bundle savedInstanceState) {17 super.onCreate(savedInstanceState);18 setContentView(R.layout.activity_image);19 initViews();20 }21 /**22 * 初始化Views23 */24 private void initViews(){25 iv_circle =(ZQImageViewRoundOval)findViewById(R.id.cicle);26 iv_roundRect =(ZQImageViewRoundOval)findViewById(R.id.roundRect);27 iv_oval =(ZQImageViewRoundOval)findViewById(R.id.oval);28 29 30 iv_roundRect.setType(ZQImageViewRoundOval.TYPE_ROUND);31 iv_roundRect.setRoundRadius(6);//矩形凹行大小32 33 iv_oval.setType(ZQImageViewRoundOval.TYPE_OVAL);34 iv_oval.setRoundRadius(45);//圆角大小35 }36 }
源码下载:
Eclipse下载:
AndroidStudio下载: