android 自定义ImageView实现圆形压缩图片

自定义属性


在values下创建文件attrs.xml文件(文件名自定义)
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CircleImageView"> //需要创建CircleImageView类
        <attr name="width" format="dimension"/>
        <attr name="src" format="reference"/>
    </declare-styleable>
</resources>
这里只定义了两个属性,一个是图片的大小,也就是直径,一个是图片的来源。

继承ImageView类


创建自定义的类CircleImageView继承ImageView,重写方法,实现圆形ImageView。
public class CircleImageView extends ImageView {

    private int radius;  //圆形图片的半径
    private Bitmap src;  //图片来源

    private int mWidth;
    private int mHeight;
    private TypedArray typedArray;  //用来获取用户给的属性值

    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);
//      获取自定义属性
        typedArray = context.obtainStyledAttributes(attrs,                      R.styleable.CircleImageView,defStyleAttr,0);
        radius = (int) typedArray.getDimension(R.styleable.CircleImageView_radius,dp2px(50));
        src = BitmapFactory.decodeResource(getResources(),typedArray.getResourceId(R.styleable.CircleImageView_src,0));
        typedArray.recycle();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);

        if (specMode == MeasureSpec.EXACTLY){
            mWidth = specSize;
        } else{
            int widthByImg = getPaddingLeft() + getPaddingRight() + src.getWidth();
            if (specMode == MeasureSpec.AT_MOST){
                mWidth = Math.min(widthByImg, specSize);
            } else
                mWidth = widthByImg;
        }

        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);
        if(specMode == MeasureSpec.EXACTLY){
            mHeight = specSize;
        }else{
            int heightByImg = getPaddingTop() + getPaddingBottom() + src.getHeight();
            if(specMode == MeasureSpec.AT_MOST){
                mHeight = Math.min(heightByImg,specSize);
            }else{
                mHeight = heightByImg;
            }
        }
        setMeasuredDimension(mWidth,mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int min = Math.min(mWidth, mHeight);
        src = Bitmap.createScaledBitmap(src, min, min, false);
        canvas.drawBitmap(createCircleImage(src, min), 0, 0, null);
    }

    private Bitmap createCircleImage(Bitmap source, int min)
    {
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap target = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(target);
        canvas.drawCircle(min / 2, min / 2, min / 2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(source, 0, 0, paint);
        return target;
    }

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

使用


增加命名空间:
 xmlns:CircalImageView="http://schemas.android.com/apk/res-auto
引用包名使用自定义ImageView
<com.alex.gy.CircleImageView
            android:layout_width="60dp"
            android:layout_height="60dp"
            CircalImageView:src="@drawable/boy"
            />

效果


效果图

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值