android 自定義ImageView顯示圓形圖片

做個安卓客戶端,在個人中心頁面要用到一個圓形圖片,系統好像沒有自帶這種樣式,得自定義一個ImageView來實現

更多內容可以訪問我的個人網站: https://www.cjluzzl.cn

java代碼

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;
//這裏導入你自己的R文件
//import cn.cjluzzl.tbt.tbtproject.R;

/**
 * Created by
 * "cjluzzl"
 * on 2017/9/18 17:04.
 */




public class CircleImageView extends ImageView {

    private static final Xfermode MASK_XFERMODE;
    private Bitmap mask;
    private Paint paint;
    private int mBorderWidth = 10;
    private int mBorderColor = Color.parseColor("#f2f2f2");

    static {
        PorterDuff.Mode localMode = PorterDuff.Mode.DST_IN;
        MASK_XFERMODE = new PorterDuffXfermode(localMode);
    }

    public CircleImageView(Context paramContext) {
        super(paramContext);
    }

    public CircleImageView(Context paramContext, AttributeSet paramAttributeSet) {
        this(paramContext, paramAttributeSet, 0);
    }

    public CircleImageView(Context paramContext, AttributeSet paramAttributeSet, int paramInt) {
        super(paramContext, paramAttributeSet, paramInt);
        TypedArray a = paramContext.obtainStyledAttributes(paramAttributeSet, R.styleable.CircularImage);
        mBorderColor = a.getColor(R.styleable.CircularImage_border_color, mBorderColor);
        final int defalut = (int) (2 * paramContext.getResources().getDisplayMetrics().density + 0.5f);
        mBorderWidth = a.getDimensionPixelOffset(R.styleable.CircularImage_border_width, defalut);
        a.recycle();
    }

    private boolean useDefaultStyle = false;

    public void setUseDefaultStyle(boolean useDefaultStyle) {
        this.useDefaultStyle = useDefaultStyle;
    }

    @Override
    protected void onDraw(Canvas paramCanvas) {
        if (useDefaultStyle) {
            super.onDraw(paramCanvas);
            return;
        }
        final Drawable localDrawable = getDrawable();
        if (localDrawable == null)
            return;
        if (localDrawable instanceof NinePatchDrawable) {
            return;
        }
        if (this.paint == null) {
            final Paint localPaint = new Paint();
            localPaint.setFilterBitmap(false);
            localPaint.setAntiAlias(true);
            localPaint.setXfermode(MASK_XFERMODE);
            this.paint = localPaint;
        }
        final int width = getWidth();
        final int height = getHeight();
        /** 保存layer */
        int layer = paramCanvas.saveLayer(0.0F, 0.0F, width, height, null, 31);
        /** 設置drawable的大小 */
        localDrawable.setBounds(0, 0, width, height);
        /** 將drawable綁定到bitmap(this.mask)上面(drawable只能通過bitmap顯示出來) */
        localDrawable.draw(paramCanvas);
        if ((this.mask == null) || (this.mask.isRecycled())) {
            this.mask = createOvalBitmap(width, height);
        }
        /** 將bitmap畫到canvas上面 */
        paramCanvas.drawBitmap(this.mask, 0.0F, 0.0F, this.paint);
        /** 將畫布複製到layer上 */
        paramCanvas.restoreToCount(layer);
        drawBorder(paramCanvas, width, height);
    }

    /**
     * 繪製最外面的邊框
     *
     * @param canvas
     * @param width
     * @param height
     */
    private void drawBorder(Canvas canvas, final int width, final int height) {
        if (mBorderWidth == 0) {
            return;
        }
        final Paint mBorderPaint = new Paint();
        mBorderPaint.setStyle(Paint.Style.STROKE);
        mBorderPaint.setAntiAlias(true);
        mBorderPaint.setColor(mBorderColor);
        mBorderPaint.setStrokeWidth(mBorderWidth);
        /**
         * 座標x:view寬度的一般 座標y:view高度的一般 半徑r:因爲是view的寬度-border的一半
         */
        canvas.drawCircle(width >> 1, height >> 1, (width - mBorderWidth) >> 1, mBorderPaint);
        canvas = null;
    }

    /**
     * 獲取一個bitmap,目的是用來承載drawable;
     * <p>
     * 將這個bitmap放在canvas上面承載,並在其上面畫一個橢圓(其實也是一個圓,因爲width=height)來固定顯示區域
     *
     * @param width
     * @param height
     * @return
     */
    public Bitmap createOvalBitmap(final int width, final int height) {
        Bitmap.Config localConfig = Bitmap.Config.ARGB_8888;
        Bitmap localBitmap = Bitmap.createBitmap(width, height, localConfig);
        Canvas localCanvas = new Canvas(localBitmap);
        Paint localPaint = new Paint();
        final int padding = mBorderWidth - 3;
        /**
         * 設置橢圓的大小(因爲橢圓的最外邊會和border的最外邊重合的,如果圖片最外邊的顏色很深,有看出有棱邊的效果,所以爲了讓體驗更加好,
         * 讓其縮進padding px)
         */
        RectF localRectF = new RectF(padding, padding, width - padding, height - padding);
        localCanvas.drawOval(localRectF, localPaint);
        return localBitmap;
    }
}

styles.xml代碼

<resources>
    <declare-styleable name="CircularImage">
        <attr name="border_width" format="dimension" />
        <attr name="border_color" format="color" />
    </declare-styleable>
</resources>

在layout佈局文件中的使用

<你的CircleImageView所在包名.CircleImageView
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:src="@drawable/my_launcher2"
            />

這樣就實現了一個自定義ImageView。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章