先上代码:
package com.andy.oschina_android.widget; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; public class CircleImageView extends View { private Paint mPaint; private RectF mBound; private Bitmap mImageBitmap; private float mRadius; public CircleImageView(Context context) { this(context,null); } public CircleImageView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mBound = new RectF(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int vw,vh; vw = vh =0; int iw,ih; if(mImageBitmap==null){ iw = ih = 0; }else{ iw = mImageBitmap.getWidth(); ih = mImageBitmap.getHeight(); } int size = Math.min(iw,ih); setMeasuredDimension(size,size); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { if(w!=oldw||h!=oldh){ /** * 设置边界,剧中显示 */ int iw,ih; if(mImageBitmap==null){ iw = ih = 0; }else{ iw = mImageBitmap.getWidth(); ih = mImageBitmap.getHeight(); } int size = Math.min(getHeight(),getWidth()); mBound.set(0,0,size,size); mRadius = size/2; if(mPaint.getShader()!=null){ Matrix m = new Matrix(); if(iw>ih){ m.setTranslate((iw-ih)/2,0); }else{ m.setTranslate(0,(ih-iw)/-2); } mPaint.getShader().setLocalMatrix(m); } } } @Override protected void onDraw(Canvas canvas) { if(mImageBitmap!=null) { canvas.drawRoundRect(mBound, mRadius, mRadius, mPaint); } } /** * 由图片决定View的大小 * @param bitmap */ public void setImageBitmap(Bitmap bitmap){ if(bitmap!=mImageBitmap){ mImageBitmap = bitmap; if(bitmap!=null) { BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(bs); }else{ mPaint.setShader(null); } requestLayout(); } } }
效果图:
思路:
这里实现圆的方式是定义一个正方形的View,通过圆角(1/4圆)的方式实现
以上代码主要做了三件事:
1、测量view的大小
2、设定绘制编辑,设置偏移量
3、设置BitmapSharder
方法onMeasure()在测量view大小时被调用,在该方法中的末尾调用了setMeasuredDimension();,这个方法设置的高宽就是最终view的高宽。
在onSizeChanged()方法中根据图片的大小设置了矩形边界和圆角半径;同时创建一个Matrix,通过Matrix设置偏移量,最后把Matrix通过方法setLocalMatrix()设置给了BitmapShader对象,这里的BitmapShader对象就是setImageBitmap()方法中创建的。
onDraw()代码一目了然,就不在说了。
setImageBitmap()是自定义方法,用于将图片设置给view。在这个方法中主要干了两个事情,一是创建一个BitmapShader,用于存放图片的像素;二是请求重绘控件。
时间: 2024-10-05 04:34:12