自定义圆角图片

65 阅读1分钟
package com.alibaba.genie.panel.basic.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;

import com.alibaba.genie.panel.basic.R;
import com.alibaba.genie.panel.basic.utils.NumberUtils;


public class RoundedImageView extends AppCompatImageView {
    private float radius;
    private int borderColor;
    private float borderWidth;
    private Paint paintDrawable;
    private Paint paintBorder;
    private RectF rectF;

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

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

    public RoundedImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.RoundedImageView);
        radius = ta.getDimension(R.styleable.RoundedImageView_cornerRadius, 16.0f);
        borderColor = ta.getColor(R.styleable.RoundedImageView_nBorderColor, Color.WHITE);
        borderColor = ta.getColor(R.styleable.RoundedImageView_nBorderColor, Color.WHITE);
        borderWidth = ta.getDimension(R.styleable.RoundedImageView_nBorderWidth, 0);
        ta.recycle();

        paintDrawable = new Paint();
        paintDrawable.setAntiAlias(true);

        paintBorder = new Paint(Paint.ANTI_ALIAS_FLAG);
        paintBorder.setColor(borderColor);
        paintBorder.setStrokeWidth(borderWidth);
    }

    private boolean drawBorder() {
        return borderWidth > 0;
    }

    private void updateDrawableRectF(int w, int h) {
        if (drawBorder()) {
            rectF = new RectF(borderWidth, borderWidth, w - borderWidth * 2, h - borderWidth * 2);
        } else {
            rectF = new RectF(0, 0, w, h);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        updateDrawableRectF(w, h);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Drawable drawable = getDrawable();
        if (drawable == null) {
            return;
        }
        drawableBorder(canvas);
        drawableBitmap(canvas, drawable);
    }

    private void drawableBorder(Canvas canvas) {
        if (!drawBorder()) {
            return;
        }
        canvas.drawRoundRect(0, 0, getWidth(), getHeight(), radius, radius, paintBorder);
    }

    private void drawableBitmap(Canvas canvas, Drawable drawable) {
        Bitmap bitmap = getBitmapFromDrawable(drawable);
        if (bitmap != null) {
            BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
            paintDrawable.setShader(shader);

            if (rectF == null) {
                updateDrawableRectF(getWidth(), getHeight());
            }

            canvas.drawRoundRect(rectF, radius, radius, paintDrawable);
        }
    }

    private Bitmap getBitmapFromDrawable(Drawable drawable) {
        if (drawable == null) {
            return null;
        }

        int width = getWidth();
        int height = getHeight();

        if (width == 0 || height == 0) {
            return null;
        }

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        float scale = Math.max((float) width / drawable.getIntrinsicWidth(),
                (float) height / drawable.getIntrinsicHeight());

        int scaledWidth = Math.round(scale * drawable.getIntrinsicWidth());
        int scaledHeight = Math.round(scale * drawable.getIntrinsicHeight());
        int dx = (width - scaledWidth) / 2;
        int dy = (height - scaledHeight) / 2;

        canvas.save();
        canvas.translate(dx, dy);
        canvas.scale(scale, scale);
        drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
        drawable.draw(canvas);
        canvas.restore();

        return bitmap;
    }

    public void setCornerRadius(float radius) {
        if (!NumberUtils.equalsFloat(this.radius, radius)) {
            this.radius = radius;
            invalidate();
        }
    }

    public void setBorderWidth(float borderWidth) {
        if (!NumberUtils.equalsFloat(this.borderWidth, borderWidth)) {
            this.borderWidth = borderWidth;
            updateDrawableRectF(getWidth(), getHeight());
            invalidate();
        }
    }

}