1. 程式人生 > >ImageView實現圓形展示以及新增邊框、內邊框

ImageView實現圓形展示以及新增邊框、內邊框

package com.tripshop.trip.ui.customview;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;

/**
 * Created by luyujian on 2018/9/28.
 * 圓形的imageView
 */

public class RoundImageView extends AppCompatImageView {
    private Xfermode xfermode;

    private int width;
    private int height;
    private float radius;

    private RectF srcRectF;

    //帶有邊框的圓形ImageView的寬度
    private int borderWidth;
    //帶有邊框的圓形ImageView的顏色
    private int borderColor;
    //是否是帶邊框的圓形ImageView
    private boolean isBorderRound;

    //帶有邊框的圓形ImageView的內邊框寬度
    private int innerBorderWidth;
    //帶有邊框的圓形ImageView的內邊框顏色
    private int innerBorderColor;
    //是否是帶邊框的並且帶有內邊框的圓形ImageView
    private boolean isInnerBorderRound;

    private Path path = new Path();
    private Paint paint = new Paint();

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

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

    public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        srcRectF = new RectF();
        xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        radius = Math.min(width, height) / 2.0f;
        srcRectF.set(width / 2.0f - radius, height / 2.0f - radius, width / 2.0f + radius, height / 2.0f + radius);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // 使用圖形混合模式來顯示指定區域的圖片
        canvas.saveLayer(srcRectF, null, Canvas.ALL_SAVE_FLAG);
        float sx = 1.0f * width / width;
        float sy = 1.0f * height / height;
        // 縮小畫布,使圖片內容不被border、padding覆蓋
        canvas.scale(sx, sy, width / 2.0f, height / 2.0f);

        super.onDraw(canvas);
        paint.reset();
        path.reset();

        path.addCircle(width / 2.0f, height / 2.0f, radius, Path.Direction.CCW);

        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        paint.setXfermode(xfermode);
        canvas.drawPath(path, paint);
        paint.setXfermode(null);

        // 恢復畫布
        canvas.restore();

        //畫圓角ImageView的邊框
        if (isBorderRound) {
            drawRoundBorder(canvas);
        }
    }

    /**
     * 設定帶有邊框的圓角ImageView
     *
     * @param borderWidth 邊框寬度
     * @param borderColor 邊框顏色
     */
    public void setRoundBorderImageView(int borderWidth, int borderColor) {
        this.isBorderRound = true;
        this.borderColor = borderColor;
        this.borderWidth = borderWidth;
    }

    /**
     * 設定帶有邊框的圓角ImageView
     *
     * @param borderWidth      邊框寬度
     * @param borderColor      邊框顏色
     * @param innerBorderWidth 內邊框寬度
     * @param innerBorderColor 內邊框顏色
     */
    public void setRoundBorderImageView(int borderWidth, int borderColor, int innerBorderWidth, int innerBorderColor) {
        this.isBorderRound = true;
        this.isInnerBorderRound = true;
        this.borderColor = borderColor;
        this.borderWidth = borderWidth;
        this.innerBorderWidth = innerBorderWidth;
        this.innerBorderColor = innerBorderColor;
    }

    /**
     * 畫圓角ImageView的邊框
     *
     * @param canvas 畫布
     */
    private void drawRoundBorder(Canvas canvas) {
        drawCircleBorder(canvas, borderWidth, borderColor, radius - borderWidth / 2.0f);
        if (isInnerBorderRound) {
            drawCircleBorder(canvas, innerBorderWidth, innerBorderColor, radius - borderWidth - innerBorderWidth / 2.0f);
        }
    }

    /**
     * 畫圓角ImageView的邊框
     *
     * @param canvas      畫布
     * @param borderWidth 邊框寬度
     * @param borderColor 邊框顏色
     * @param radius      弧度
     */
    private void drawCircleBorder(Canvas canvas, int borderWidth, int borderColor, float radius) {
        initBorderPaint(borderWidth, borderColor);
        path.addCircle(width / 2.0f, height / 2.0f, radius, Path.Direction.CCW);
        canvas.drawPath(path, paint);
    }


    /**
     * 初始畫圓角ImageView邊框的畫筆
     *
     * @param borderWidth 邊框寬度
     * @param borderColor 邊框顏色
     */
    private void initBorderPaint(int borderWidth, int borderColor) {
        path.reset();
        paint.setStrokeWidth(borderWidth);
        paint.setColor(borderColor);
        paint.setStyle(Paint.Style.STROKE);
    }
}