自定义圆形View视图控件

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 }
原文地址:https://www.cnblogs.com/gxclmx/p/6905524.html