制作圆形头像

来源:互联网 发布:数控车床编程语言 编辑:程序博客网 时间:2024/05/16 23:51

生活中我们见到的大多数头像都变成圆形头像,因为圆形可以给客户一种亲和感,更能被客户接受。而我们Android5.0之前,想要使用圆形头像必须要自己来手写,5.0之后自带了圆形头像为我们开发人员剩了好多事情。
闲话不多说了,直接来看一下效果。
这里写图片描述
实现分为下面几步:
1.自定义属性(attr.xml);
2.构造方法中获取属性值;
3.调用ondraw()方法;
具体的实现步骤:
1.获取图片

 @Override    public void setImageBitmap(Bitmap bm) {        super.setImageBitmap(bm);        mBitmap = bm;        setup();    }    @Override    public void setImageDrawable(Drawable drawable) {        super.setImageDrawable(drawable);        mBitmap = getBitmapFromDrawable(drawable);        setup();    }    @Override    public void setImageResource(@DrawableRes int resId) {        super.setImageResource(resId);        mBitmap = getBitmapFromDrawable(getDrawable());        setup();    }    @Override    public void setImageURI(Uri uri) {        super.setImageURI(uri);        mBitmap = getBitmapFromDrawable(getDrawable());        setup();    }

2.方法中调用了setup()方法

if (!mReady) {            mSetupPending = true;            return;        }

因为mReady默认是false的,所以只会执行前面的这一句就结束了。
3.调用构造方法获取属性值

public CircleImageView(Context context) {        super(context);        init();    }    public CircleImageView(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public CircleImageView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);//属性数组        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);        mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_border_width, DEFAULT_BORDER_WIDTH);        mBorderColor = a.getColor(R.styleable.CircleImageView_border_color, DEFAULT_BORDER_COLOR);        mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_border_overlay, DEFAULT_BORDER_OVERLAY);//回收数组        a.recycle();//调用init()方法        init();    }

4.调用init()方法

private void init() {        super.setScaleType(SCALE_TYPE);        mReady = true;//执行完setup()方法的前面部分,mSetupPending已经变成了true        if (mSetupPending) {            setup();            mSetupPending = false;        }    }

init()方法的作用只是一用来调节执行顺序的,因为一定要控制先执行构造方法拿到数据之后,然后再去执行setup()方法中的有效部分设置数据。
5.调用setup()方法中的有效部分

private void setup() {//第一次执行只能执行到这个地方        if (!mReady) {            mSetupPending = true;            return;        }        if (mBitmap == null) {            return;        }//初始化一个图片渲染器,渲染器        mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);//设置图片画笔        mBitmapPaint.setAntiAlias(true);        mBitmapPaint.setShader(mBitmapShader);//设置描边画笔        mBorderPaint.setStyle(Paint.Style.STROKE);        mBorderPaint.setAntiAlias(true);        mBorderPaint.setColor(mBorderColor);        mBorderPaint.setStrokeWidth(mBorderWidth);//获取图片的高度        mBitmapHeight = mBitmap.getHeight();        mBitmapWidth = mBitmap.getWidth();//创建一个大小和这个view一样大的矩形框        mBorderRect.set(0, 0, getWidth(), getHeight());//计算外边半径(画圆的时候会用到,外边框的中间处)        mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2, (mBorderRect.width() - mBorderWidth) / 2);        mDrawableRect.set(mBorderRect);        if (!mBorderOverlay) {        //控制mDrawableRect比mBorderRect边距空有mBorderWidth            mDrawableRect.inset(mBorderWidth, mBorderWidth);        }        mDrawableRadius = Math.min(mDrawableRect.height() / 2, mDrawableRect.width() / 2);        updateShaderMatrix();        invalidate();    }

6.调用updateShaderMatrix()方法,用来优化绘制的效果

private void updateShaderMatrix() {        float scale;        float dx = 0;        float dy = 0;        mShaderMatrix.set(null);//比较是按照宽来缩放还是按照长来缩放        if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {            scale = mDrawableRect.height() / (float) mBitmapHeight;            dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;        } else {            scale = mDrawableRect.width() / (float) mBitmapWidth;            dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;        }//mShaderMatrix对象用来对图片进行变换        mShaderMatrix.setScale(scale, scale);        mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);        mBitmapShader.setLocalMatrix(mShaderMatrix);    }

7.执行invalidate()方法,进行绘制头像

@Override    protected void onDraw(Canvas canvas) {        if (getDrawable() == null) {            return;        }        canvas.drawCircle(getWidth() / 2, getHeight() / 2, mDrawableRadius, mBitmapPaint);        if (mBorderWidth != 0) {            canvas.drawCircle(getWidth() / 2, getHeight() / 2, mBorderRadius, mBorderPaint);        }    }
0 0
原创粉丝点击