android自定义圆形ImageView,调用类

效果图:

代码:

package com.zhw.kitchen1712114150.Tool;

/**
 * Created by 得已 on 2018/7/10.
 */

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ImageView;

import com.zhw.kitchen1712114150.R;

public class RoundImageView extends android.support.v7.widget.AppCompatImageView {
    // ImageView类型
    private int type;
    // 圆形图片
    private static final int TYPE_CIRCLE = 0;
    // 圆角图片
    private static final int TYPE_ROUND = 1;
    // 默认圆角宽度
    private static final int BORDER_RADIUS_DEFAULT = 10;
    // 获取圆角宽度
    private int mBorderRadius;
    // 画笔
    private Paint mPaint;
    // 半径
    private int mRadius;
    // 缩放矩阵
    private Matrix mMatrix;
    // 渲染器,使用图片填充形状
    private BitmapShader mBitmapShader;
    // 宽度
    private int mWidth;
    // 圆角范围
    private RectF mRectF;

    public RoundImageView(Context context) {
        this(context, null);
    }

    public RoundImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RoundImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // 初始化画笔等属性
        mMatrix = new Matrix();
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        // 获取自定义属性值
        TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundImageView, defStyle, 0);
        int count = array.getIndexCount();
        for (int i = 0; i < count; i++) {
            int attr = array.getIndex(i);
            switch (attr) {
                case R.styleable.RoundImageView_borderRadius:
                    // 获取圆角大小
                    mBorderRadius = array.getDimensionPixelSize(R.styleable.RoundImageView_borderRadius, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, BORDER_RADIUS_DEFAULT, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.RoundImageView_imageType:
                    // 获取ImageView的类型
                    type = array.getInt(R.styleable.RoundImageView_imageType, TYPE_CIRCLE);
                    break;
            }
        }
        // Give back a previously retrieved StyledAttributes, for later re-use.
        array.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 如果是圆形,则强制宽高一致,以最小的值为准
        if (type == TYPE_CIRCLE) {
            mWidth = Math.min(getMeasuredWidth(), getMeasuredHeight());
            mRadius = mWidth / 2;
            setMeasuredDimension(mWidth, mWidth);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getDrawable() == null) {
            return;
        }
        // 设置渲染器
        setShader();
        if (type == TYPE_ROUND) {
            canvas.drawRoundRect(mRectF, mBorderRadius, mBorderRadius, mPaint);
        } else {
            canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
        }
    }

    private void setShader() {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        Bitmap bitmap = drawable2Bitmap(drawable);
        mBitmapShader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
        float scale = 1.0f;
        if (type == TYPE_ROUND) {
            scale = Math.max(getWidth() * 1.0f / bitmap.getWidth(), getHeight() * 1.0f / bitmap.getHeight());
        } else if (type == TYPE_CIRCLE) {
            // 取小值,如果取大值的话,则不能覆盖view
            int bitmapWidth = Math.min(bitmap.getWidth(), getHeight());
            scale = mWidth * 1.0f / bitmapWidth;
        }
        mMatrix.setScale(scale, scale);
        mBitmapShader.setLocalMatrix(mMatrix);
        mPaint.setShader(mBitmapShader);
    }

    /**
     * 将Drawable转化为Bitmap
     *
     * @param drawable
     * @return
     */
    private Bitmap drawable2Bitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        // 创建画布
        Bitmap bitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mRectF = new RectF(0, 0, getWidth(), getHeight());
    }

    /**
     * 对外公布的设置borderRadius方法
     *
     * @param borderRadius
     */
    public void setBorderRadius(int borderRadius) {
        int pxValue = dp2px(borderRadius);
        if (this.mBorderRadius != pxValue) {
            this.mBorderRadius = pxValue;
            // 这时候不需要父布局的onLayout,所以只需要调用onDraw即可
            invalidate();
        }
    }

    /**
     * 对外公布的设置形状的方法
     *
     * @param type
     */
    public void setType(int type) {
        if (this.type != type) {
            this.type = type;
            if (this.type != TYPE_CIRCLE && this.type != TYPE_ROUND) {
                this.type = TYPE_CIRCLE;
            }
            // 这个时候改变形状了,就需要调用父布局的onLayout,那么此view的onMeasure方法也会被调用
            requestLayout();
        }
    }

    /**
     * dp2px
     */
    public int dp2px(int val) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, val, getResources().getDisplayMetrics());
    }

}
自定义属性:attrs.xml


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <attr name="borderRadius" format="dimension" />
  4. <attr name="imageType">
  5. <enum name="circle" value="0" />
  6. <enum name="round" value="1" />
  7. </attr>
  8. <declare-styleable name="RoundImageView">
  9. <attr name="borderRadius" />
  10. <attr name="imageType" />
  11. </declare-styleable>
  12. </resources>

3.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <attr name="borderRadius" format="dimension" />
  4. <attr name="imageType">
  5. <enum name="circle" value="0" />
  6. <enum name="round" value="1" />
  7. </attr>
  8. <declare-styleable name="RoundImageView">
  9. <attr name="borderRadius" />
  10. <attr name="imageType" />
  11. </declare-styleable>
  12. </resources>

<com.zhw.kitchen1712114150.Tool.RoundImageView
    beyole:borderRadius="20dip"
    beyole:imageType="round"
    android:id="@+id/imageView"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginLeft="20dp"
    android:layout_marginStart="20dp"
    app:srcCompat="@mipmap/ic_launcher_round" />
<com.zhw.kitchen1712114150.Tool.RoundImageView
    beyole:borderRadius="20dip"
    beyole:imageType="circle"
    android:id="@+id/imageView11"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginLeft="20dp"
    android:layout_marginStart="20dp"
    app:srcCompat="@mipmap/ic_launcher_round" />

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <attr name="borderRadius" format="dimension" />
  4. <attr name="imageType">
  5. <enum name="circle" value="0" />
  6. <enum name="round" value="1" />
  7. </attr>
  8. <declare-styleable name="RoundImageView">
  9. <attr name="borderRadius" />
  10. <attr name="imageType" />
  11. </declare-styleable>
  12. </resources>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值