Android 打造一款逼格高的圓形圖片

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.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.tcrj.example.activity.R;

/**
 * 頭像
 * Created by leict on 2017/6/14.
 */

public class CircleImageView extends ImageView {
    private int outCiecleColor = Color.WHITE;
    private int outCiecleWidth;
    private Paint paintBorder;

    private int viewWidth;
    private int viewHeight;
    private Bitmap bitmap;

    public CircleImageView(Context context) {
        super(context);
        initAttrs(context, null);
    }

    public CircleImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);
    }

    public CircleImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initAttrs(context, attrs);
    }

    private void initAttrs(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.CiecleImageView);
            int len = array.length();
            for (int i = 0; i < len; i++) {
                int attr = array.getIndex(i);
                switch (attr) {
                    case R.styleable.CiecleImageView_outCiecleColor:
                        this.outCiecleColor = array.getColor(attr, Color.WHITE);
                        break;
                    case R.styleable.CiecleImageView_outCiecleWidth:
                        this.outCiecleWidth = (int) array.getDimension(attr, 5);
                        break;
                }
            }
        }
        paintBorder = new Paint();
        paintBorder.setColor(outCiecleColor);
        paintBorder.setAntiAlias(true);
    }

    /**
     * 測量
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measuredWidth(widthMeasureSpec);
        int height = measuredHeight(heightMeasureSpec);
        viewWidth = width - (outCiecleWidth * 2);
        viewHeight = height - (outCiecleWidth * 2);
        setMeasuredDimension(width, height);
    }

    /**
     * 加載圖片
     */
    private void loadImage() {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
        if (bitmapDrawable != null) {
            bitmap = bitmapDrawable.getBitmap();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        loadImage();
        if (bitmap != null) {
            int min = Math.min(viewHeight, viewWidth);
            int ciecleCenter = min / 2;
            bitmap = Bitmap.createScaledBitmap(bitmap, min, min, false);
            canvas.drawCircle(ciecleCenter + outCiecleWidth, ciecleCenter + outCiecleWidth, ciecleCenter + outCiecleWidth, paintBorder);
            canvas.drawBitmap(createCiecleBitmap(bitmap, min), outCiecleWidth, outCiecleWidth, null);
        }
    }

    /**
     * 創建一個圓形的Bitmap
     *
     * @param image
     * @param min
     * @return
     */
    private Bitmap createCiecleBitmap(Bitmap image, int min) {
        Bitmap mBitmap = null;
        Paint mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mBitmap = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(mBitmap);
        canvas.drawCircle(min / 2, min / 2, min / 2, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(image, 0, 0, mPaint);
        return mBitmap;
    }

    /**
     * 測量寬度
     *
     * @param widthMeasureSpec
     * @return
     */
    private int measuredWidth(int widthMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(widthMeasureSpec);
        int size = MeasureSpec.getSize(widthMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = viewWidth;
        }
        return result;
    }

    /**
     * 測量高度
     *
     * @param heightMeasureSpec
     * @return
     */
    private int measuredHeight(int heightMeasureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = viewHeight;
        }
        return result;
    }

    /**
     * 動態設置顏色
     *
     * @param color
     */
    public void setBorderColor(int color) {
        if (paintBorder != null) {
            paintBorder.setColor(color);
        }
        this.invalidate();
    }

    /**
     * 動態設置寬度
     *
     * @param width
     */
    public void setBorderWidth(int width) {
        this.outCiecleWidth = width;
        this.invalidate();
    }
}

在value文件夾下新建一個attrs文件:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CiecleImageView">
        <attr name="outCiecleColor" format="color"></attr>
        <attr name="outCiecleWidth" format="dimension"></attr>
    </declare-styleable>
</resources>

 XML文件佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="@dimen/height_10"
    android:orientation="vertical">

    <com.tcrj.example.image.CircleImageView
        android:id="@+id/imgview"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@mipmap/face4" />
</LinearLayout>
動態設置表框的寬度及顏色:
imgview = (CircleImageView) findViewById(R.id.imgview);
imgview.setBorderColor(Color.RED);
imgview.setBorderWidth(10);

效果圖如下:

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