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 }