制作圆形头像

生活中我们见到的大多数头像都变成圆形头像,因为圆形可以给客户一种亲和感,更能被客户接受。而我们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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可生成圆形、方形、及方形的组合头像。项目地址:https://github.com/Pedroafa/avatar-android 效果图:如何使用:首先创建个ImageView<ImageView             android:id="@ id/roundedAvatar"             android:layout_height="fill_parent"             android:layout_width="fill_parent"/>2. //通过AvatarDrawableFactory生成各种形状的Drawable AvatarDrawableFactory avatarDrawableFactory = new AvatarDrawableFactory(getResources()); BitmapFactory.Options options = new BitmapFactory.Options(); options.inMutable = false; Bitmap avatar = BitmapFactory.decodeResource(getResources(), R.drawable.avatar, options); //圆形的 Drawable roundedAvatarDrawable = avatarDrawableFactory.getRoundedAvatarDrawable(avatar);//生成圆形的Drawable ImageView roundedAvatarView = (ImageView)rootView.findViewById(R.id.roundedAvatar); roundedAvatarView.setImageDrawable(roundedAvatarDrawable);其他形状的://圆形的且带边框的 Drawable borderedRoundedAvatarDrawable = avatarDrawableFactory.getBorderedRoundedAvatarDrawable(avatar); ImageView borderedRoundedAvatarView = (ImageView)rootView.findViewById(R.id.borderedRoundedAvatar); borderedRoundedAvatarView.setImageDrawable(borderedRoundedAvatarDrawable); //方形的 Drawable squaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar); ImageView squaredAvatarView = (ImageView)rootView.findViewById(R.id.squaredAvatar); squaredAvatarView.setImageDrawable(squaredAvatarDrawable); //俩个方形的组合头像 Drawable doubleSquaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar, avatar); ImageView doubleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.doubleSquaredAvatar); doubleSquaredAvatarView.setImageDrawable(doubleSquaredAvatarDrawable); //三个方形的组合头像 Drawable tripleSquaredAvatarDrawable = avatarDrawableFactory.getSquaredAvatarDrawable(avatar, avatar, avatar); ImageView tripleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.tripleSquaredAvatar); tripleSquaredAvatarView.setImageDrawable(tripleSquaredAvatarDrawable); //四个方形的组合头像 Drawable quadrupleSquaredAvatarDrawable = avatarDrawableFactory                     .getSquaredAvatarDrawable(avatar, avatar, avatar, avatar); ImageView quadrupleSquaredAvatarView = (ImageView)rootView.findViewById(R.id.quadrupleSquaredAvatar); quadrupleSquaredAvatarView.setImageDrawable(quadrupleSquaredAvatarDrawable);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值