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作为着色器来创建一个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转bitmap 121 * 122 * @paramdrawable 123 * @return 124 */ 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转单位px 140 */ 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 mType 153 */ 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 * @parammRoundRadius 167 */ 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 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.activity_image); 19 initViews(); 20 } 21 /** 22 * 初始化Views 23 */ 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下载:http://download.csdn.net/detail/dickyqie/9621330
AndroidStudio下载:https://github.com/DickyQie/android-imageview